TL; DR
你想要一个one-to-many关系。
from sqlalchemy import ForeignKey, Integer, Column
from sqlalchemy.orm import relationship
class Widget(Base):
__tablename__ = 'widget'
widget_id = Column(Integer, primary_key=True)
# name columns, type columns, ...
json = Column(JSONDict)
class ClazzB(Base):
__tablename__ = 'clazzb'
clazzb_id = Column(Integer, primary_key=True)
# Your "attributeB"
widget_id = Column(Integer,
ForeignKey('widget.widget_id',
onupdate='cascade',
ondelete='cascade'),
nullable=False)
widget = relationship('Widget')
# possible association_proxy
#widget_json = association_proxy('widget', 'json')
使用关系
定义模型和ClazzB
之间ClazzA
relationship。由于我们没有全貌,下面的定义只是一些例子。
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
class ClazzA(Base): # replace Base with the base class of your models
__tablename__ = 'clazza' # replace with the real tablename
# T is the type of your primary key, the column name is just an example
clazza_id = Column(T, primary_key=True)
class ClazzB(Base):
# The column that will relate this model to ClazzA
clazza_id = Column(T, ForeignKey('clazza.clazza_id',
onupdate='cascade',
ondelete='cascade'),
nullable=False)
# A handy accessor for relationship between mapped classes,
# not strictly required. Configurable to be either very lazy
# (loaded if accessed by issuing a SELECT) or eager (JOINed
# when loading objectB for example)
objectA = relationship('ClazzA')
现在不是增加的ClazzA
attributeA
参考,ClazzB
相关objectA
添加引用objectB
的初始化。现在
objectB = ClazzB(..., objectA=objectA)
两个是相关的,通过objectB
访问的相关objectA
attributeA
做
objectB.objectA.attributeA
无需跟踪更改attributeA
,因为它是实例的attributeA
。
现在,如果你必须有一个属性attributeB
上ClazzB
(避免重构现有的代码或一些这样的),你可以添加属性
class ClazzB:
@property
def attributeB(self):
return self.objectA.attributeA
将与
返回相关
objectA
的
attributeA
objectB.attributeB
objectB.attributeB['something'] = 'else'
等等。
还有一个SQLAlchemy方法用于访问跨关系的属性:association proxy。它支持简单的查询,但不是例如可下载的。
class ClazzB(Base):
attributeB = association_proxy('objectA', 'attributeA')
如果您希望ClazzB.attributeB
从JSONDict
某些项下获得的值,比如,你可以使用类似这样
class ClazzB(Base):
key = Column(Unicode)
@property
def attributeB(self):
return self.objectA.attributeA[self.key]
您也可以attributeB
工作作为一流水平的SQL表达式使用hybrid properties,如果你需要这样的事情。但是你必须自己编写你的类级表达式。
ClazzB是另一个模型吗?你需要坚持这种模式吗? – univerio
@univerio是的,ClazzB也需要坚持。 – ChaimKut
您的模型'ClazzA'和'ClazzB'在数据库级别有明确的关系吗?换句话说,如果我们只是得到一个类似“ClazzA.attributeA被更改为这个实例”的事件,有没有办法说“这个ClazzA实例与该ClazzB实例有关?”? –