我正在尝试从SQLAlchemy中的字典值创建一个表。我正在使用Flask,目前我的班级看起来像这样:
class Machine(db.Model):
"""Template for the Machine Info table"""
__tablename__ = 'machine'
id = db.Column(db.Integer, primary_key=True)
machine_name = db.Column(db.String(32))
date = db.Column(db.String(32))
time = db.Column(db.String(32))
sensor1 = db.Column(db.String(32))
sensor2 = db.Column(db.String(32))
这很好用,但我的问题是我最终会在这个表中有很多列,可能是+100。我宁愿不填写我的models.py文件,包含100行这类东西。我希望将它放在自己的字典中,在自己的文件中,字典看起来像这样:
SENSOR_LOOKUP_DICT = {
"machine_name":"machine_name",
"date":"date",
"time":"time",
"sensor1":"sensor1",
"sensor2":"sensor2"
}
列表可能也适用于此。
我在想我可以使用某种循环,如下所示:
class Machine(db.Model):
"""Template for the Machine Info table"""
__tablename__ = 'machine'
id = db.Column(db.Integer, primary_key=True)
for sensor in SENSOR_LOOKUP_DICT:
sensor = db.Column(db.String(32))
但这只是给我一个名为传感器的专栏。我在sqlalchemy中找到了几个相关的问题,但他们没有使用这种结构来创建表格。我非常喜欢一个方法,如果可能的话,继续使用db.Model结构,而不是使用create_engine的结构,因为稍后的一些JSON序列化对于这种结构更容易(以及一些应用程序结构的东西)。有没有办法做到这一点?
答案 0 :(得分:1)
您可以将设计拆分为机器和传感器表,而不是将所有传感器值填入a single row of hundred or more columns:
from datetime import datetime
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.ext.associationproxy import association_proxy
class Machine(db.Model):
"""The Machine Info table"""
__tablename__ = 'machine'
id = db.Column(db.Integer, primary_key=True)
machine_name = db.Column(db.String(32))
datetime = db.Column(db.DateTime, default=datetime.utcnow)
sensors = db.relationship(
'Sensor',
collection_class=attribute_mapped_collection('name'),
cascade='all, delete-orphan')
sensor_values = association_proxy(
'sensors', 'value',
creator=lambda k, v: Sensor(name=k, value=v))
class Sensor(db.Model):
"""The Sensor table"""
__tablename__ = 'sensor'
machine_id = db.Column(db.Integer, db.ForeignKey('machine.id'),
primary_key=True)
# Note that this could be a numeric ID as well
name = db.Column(db.String(16), primary_key=True)
value = db.Column(db.String(32))
dictionary collection relationship与association proxy结合使您可以像这样处理传感器值:
In [10]: m = Machine(machine_name='Steam Machine')
In [11]: m.sensor_values['sensor1'] = 'some interesting value'
In [12]: db.session.add(m)
In [13]: db.session.commit()
In [14]: m.sensor_values
Out[14]: {'sensor1': 'some interesting value'}
In [16]: m.sensor_values['sensor1']
Out[16]: 'some interesting value'
使用单独的表而不是固定模式的另一个好处是,如果您在生命中稍后添加传感器,则无需迁移模式以适应这种情况 - 换句话说,无需更改表以添加列。只需像以前一样将新的传感器值添加到传感器表中。
最后,一些RDBMS支持不同类型的文档类型,例如您可以使用的Postgresql的hstore,json和jsonb列,因为传感器表本质上是一个键/值存储。