我一直在玩,使用Flask-AppBuilder构建一个简单的CRUD 应用。除了具有多个外键的表之外,视图工作顺利 与同一个表的关系。当我尝试对JOINed列进行排序时,sqlalchemy 抱怨混乱的关系。
在这个应用程序中,我们有 Child ,它与两个 Adults 有关系:
class Adult(Model):
adult_id = Column(Integer, primary_key=True)
name = Column(String(50))
class Child(Model):
child_id = Column(Integer, primary_key=True)
name = Column(String(50))
adult1_id = Column(Integer, ForeignKey('adult.adult_id'))
adult2_id = Column(Integer, ForeignKey('adult.adult_id'))
# We can also use foreign_keys to setup the relationships
# This makes the view work (until you sort)
adult1 = relationship("Adult", lazy='joined', backref='Adult1', primaryjoin='Adult.adult_id == Child.adult1_id')
adult2 = relationship("Adult", lazy='joined', backref='Adult2', primaryjoin='Adult.adult_id == Child.adult2_id')
视图正确显示与孩子相关的每个成人的姓名
class ChildView(ModelView):
datamodel = SQLAInterface(Child)
list_columns = ['child_id', 'name', 'adult1.name', 'adult2.name']
但是当我们尝试按成人名称排序时,我们会得到一个追溯:
InvalidRequestError: Could not find a FROM clause to join from. Tried joining
to <class 'app.models.Adult'>, but got: Can't determine join between 'child'
and 'adult'; tables have more than one foreign key constraint relationship
between them. Please specify the 'onclause' of this join explicitly.
我可以通过解决方法禁用对列的排序,但我会这样做 我真的很想了解我所缺少的东西。
完整代码在https://github.com/cwebber314/fab_multiple_fk
按Adult1.name
或Adult2.name
排序的完整追溯:
<snip irrelevant stuff here...>
File "c:\anaconda2\lib\site-packages\flask_appbuilder\views.py", line 475, in list
widgets = self._list()
File "c:\anaconda2\lib\site-packages\flask_appbuilder\baseviews.py", line 877, in _list
page_size=page_size)
File "c:\anaconda2\lib\site-packages\flask_appbuilder\baseviews.py", line 791, in _get_list_widget
count, lst = self.datamodel.query(joined_filters, order_column, order_direction, page=page, page_size=page_size)
File "c:\anaconda2\lib\site-packages\flask_appbuilder\models\sqla\interface.py", line 94, in query
query = query.join(model_relation)
File "c:\anaconda2\lib\site-packages\sqlalchemy\orm\query.py", line 2010, in join
from_joinpoint=from_joinpoint)
File "<string>", line 2, in _join
File "c:\anaconda2\lib\site-packages\sqlalchemy\orm\base.py", line 201, in generate
fn(self, *args[1:], **kw)
File "c:\anaconda2\lib\site-packages\sqlalchemy\orm\query.py", line 2154, in _join
outerjoin, full, create_aliases, prop)
File "c:\anaconda2\lib\site-packages\sqlalchemy\orm\query.py", line 2227, in _join_left_to_right
self._join_to_left(l_info, left, right, onclause, outerjoin, full)
File "c:\anaconda2\lib\site-packages\sqlalchemy\orm\query.py", line 2356, in _join_to_left
"Tried joining to %s, but got: %s" % (right, ae))
InvalidRequestError: Could not find a FROM clause to join from. Tried joining
to <class 'app.models.Adult'>, but got: Can't determine join between 'child'
and 'adult'; tables have more than one foreign key constraint relationship
between them. Please specify the 'onclause' of this join explicitly.
答案 0 :(得分:0)
我认为我在一段时间之前遇到了同样的问题并且这有效:
float_lenght = Column(Float)
fkey_lenght_unit = Column(Integer, ForeignKey('unitlist.id'))
unit_lenght = relationship("UnitList", foreign_keys=[fkey_lenght_unit])
float_width = Column(Float)
fkey_width_unit = Column(Integer, ForeignKey('unitlist.id'))
unit_width = relationship("UnitList", foreign_keys=[fkey_width_unit])
float_height = Column(Float)
fkey_height_unit = Column(Integer, ForeignKey('unitlist.id'))
unit_height = relationship("UnitList", foreign_keys=[fkey_height_unit])
所以也许试试:
adult2_id = Column(Integer, ForeignKey('adult.adult_id'))
adult2 = relationship("Adult", foreign_keys=[adult2_id ])