这与这个从未被回答过的问题有关。
我们试图在现有模式(我们无法更改)上建立一个flask-sqlachemy项目,并决定声明性语法,这样我们就可以以一种明智的方式将类组织成多个文件进行维护。这适用于我们的大多数关系,除了一些我们称之为属性表的东西,因为缺少更好的术语。这些是一些主要对象的一对一叶表,通常包含属性的某种受控词汇表。ORM中的目标是映射所有这些(其中有许多)类型的表,就像它们是主表的属性一样。
下面是一个包含两个表的SQA示例:
class MarkerType(db.Model):
__tablename__="mrk_types"
_marker_type_key = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String())
class Marker(db.Model):
__tablename__="mrk_marker"
_marker_key=db.Column(db.Integer,primary_key=True)
_marker_type_key=db.Column(db.Integer())
我们想要访问markertype.name,就像我们说marker.markertype,或者在查询中说marker.markertype=='thing'。我唯一可以管理的方法是在marker类中使用column_属性,如下所示:
markertype = db.column_property(
db.select([MarkerType.name]).
where(MarkerType._marker_type_key==_marker_type_key)
)
然而,我似乎找不到如何用声明性的方式来实现这一点,也许这种方式并不存在。有没有一个明智的方法可以做到这一点,而不必担心我的进口,甚至更糟的我的班级秩序?因为我们有数百个表要映射,所以如果我们必须担心类和导入顺序,我可以看到这是一个维护噩梦。
如果所有这些都是完全不可能的,一厢情愿的想法,那么映射这些表的更好方法是什么?
最佳答案
这听起来是Association Proxy的一个很好的用例。这将代理相关模型的字段。在这种情况下,实施将是:
from sqlalchemy.orm import relationship
from sqlalchemy.ext.associationproxy import association_proxy
class MarkerType(db.Model):
__tablename__="mrk_types"
_marker_type_key = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
class Marker(db.Model):
__tablename__="mrk_marker"
_marker_key=db.Column(db.Integer,primary_key=True)
_marker_type_key=db.Column(db.Integer, ForeignKey('mrk_types._marker_type_key')
mt = relationship(MarkerType, uselist=False)
marker_type = association_proxy('mt', 'name')
这允许像
session.query(Marker).filter_by(marker_type='my_marker_type')
marker_type
字段是markerType对象上name
字段的代理。该对象可由mt
字段(关系字段)引用。注意
uselist=False
。这表示每个标记都有一个标记类型。关系自动检测并使用ForeignKey。