我想知道如何在数据库中以干净的方式保存计算值:
示例(摘自SQLAlchemy手册):
Base = declarative_base()
class Interval(Base):
__tablename__ = 'interval'
id = Column(Integer, primary_key=True)
start = Column(Integer)
end = Column(Integer)
@hybrid_property
def length(self):
return self.end - self.start
因此length
被计算出来。但是为了更方便地查询(在另一个数据库工具中),我希望将这个length
也保存到表中
因此,我的第一个粗略测试就是简单地添加:length = Column(Float)
。显然,这不起作用(但我想我还是会尝试一下:p),因为length方法会覆盖length列
现在我唯一能想到的方法就是在init&;中计算它;遵从super(),如下所示:
Base = declarative_base()
class Interval(Base):
__tablename__ = 'interval'
id = Column(Integer, primary_key=True)
start = Column(Integer)
end = Column(Integer)
length = Column(Integer)
def __init__(self, *args, **kwargs):
kwargs['length'] = kwargs['end'] - kwargs['start']
super().__init__(*args, **kwargs)
然而,我觉得应该有一个更干净的方法。有吗
谢谢
您可以在sqlalchemy中使用column_property特性,而不是混合属性
column\u property:column\u property()函数可用于以类似于常规映射列的方式映射SQL表达式。使用此技术,在加载时将该属性与所有其他列映射属性一起加载
注意:您还可以
query
在列的属性上查询示例:
有几种方法可以解决这个问题
一种是使用^{} 和
before_insert
触发器。这是一种SQLAlchemy技术,自动检测对模型的更改,并在将行写入服务器之前调度事件。然后,您可以使用它来抢占保存,潜在地查看哪些列已更改,然后相应地更新length
另一种是使用
generated
或computed column
。这些已经在[Postgres 12](generated columns)中引入,它们也出现在MySQL、Oracle和MS SQL Server中——尽管我对此知之甚少。 它们基本上做相同的事情,但您只需将该逻辑添加到表定义中,就可以随意忽略它。SQLAlchemy从1.3.11开始支持它们相关问题 更多 >
编程相关推荐