假设我有一个班级Interaction
。我的程序以每个交互更新分数表的方式处理interactions
。 Interaction
被声明为数据库表的精确映射,但我也希望它引用ScoreTable
的相关实例。 ScoreTable
是一个包含分数的类,并控制业务逻辑以更新分数:
class Interaction(Base):
__tablename__ = 'interactions'
#Mirror the table's structure
anomaly_id = Column(Integer, ForeignKey('anomalies.id'), primary_key=True)
user_id = Column(Integer, primary_key=True) # ForeignKey('users.id'),
feedback_score = Column(Integer)
#scoreUpdater is another (non-ORM) object I want this instance to be aware of
myScoreUpdater= ...
由Interaction
提取的query()
的所有实例都将共享相同的ScoreUpdater
。因此,当我运行query()
以获取Interactions
的所有实例时,我能以某种方式告诉query()
将scoreUpdater
设置为某个值,在同一个进程中吗?另外,如果query()
克隆并填充ORM数据,我可以给Interaction
半建模板实例吗?
我读过我可以修改标准构造函数来执行某些任务,但不知道如何通过query()
我想另一种方法是首先运行query
并让它填充与ORM相关的字段,然后在第二步中迭代查询结果以设置非OM字段(即rightUpdater的正确实例)?
我是SQLalchemy的新手......并且从java转换为python。所以如果你认为我的方法根本就错了,请告诉我!
答案 0 :(得分:1)
相关的documentation on constructing objects说:
从数据库行重新创建对象时,SQLAlchemy ORM不会调用
__init__
。 ORM的过程有点类似于Python标准库的pickle
模块,调用低级__new__
方法,然后直接在实例上静默恢复属性,而不是调用__init__
。如果你需要在数据库加载的实例准备好使用它们之前做一些设置,那么有一个名为
中指定的瞬态属性非常有用InstanceEvents.load()
的事件挂钩可以实现这一点;它也可以通过名为orm.reconstructor()
的特定于类的装饰器获得。使用orm.reconstructor()
时,映射器将在每次加载或重构类的实例时调用没有参数的修饰方法。这对于重新创建通常在__init__
因此,如果我已正确理解您,您可以为Interaction
定义一个填充非ORM字段的重构器:
from sqlalchemy.orm import reconstructor
class Interaction(Base):
__tablename__ = 'interactions'
# Mirror the table's structure
anomaly_id = Column(Integer, ForeignKey('anomalies.id'), primary_key=True)
user_id = Column(Integer, primary_key=True) # ForeignKey('users.id'),
feedback_score = Column(Integer)
# myScoreUpdater is another (non-ORM) object I want this instance to be aware of
@reconstructor
def init_on_load(self):
# Do what you must to populate score updater
self.myScoreUpdater = ...
请注意,您可能希望在重构器和__init__
之间共享逻辑,因此只需将__init__
装饰为重构器,如果可以不带参数调用,或者移动初始化得分更新者的方法。
最后,如果你的ScoperUpdater
实际上不需要知道它绑定到哪个实例,你可以将它作为所有实例之间共享的类属性 - 比如Java中的静态属性。