bla*_*man 4 python sqlalchemy flask-sqlalchemy flask-restless
我使用flask-sqlalchemy有以下sqlalchemy模型。我的日程安排模型中有 3 个人才偏好项目。总是需要 3 个并且不会更少。
class TalentPref(db.Model):
__tablename__ = 'talentpref'
id = db.Column(db.Integer, primary_key=True)
firstName = db.Column(db.String(80), unique=True)
lastName = db.Column(db.String(80), unique=True)
def __init__(self, firstName, lastName):
self.firstName = firstName
self.lastName = lastName
def __repr__(self):
return '<talentpref %r %r>' % (self.firstName, self.lastName)
class Schedule(db.Model):
__tablename__ = 'schedule'
id = db.Column(db.Integer, primary_key=True)
talentpref1_id = db.Column(db.Integer, db.ForeignKey('talentpref.id'))
talentpref2_id = db.Column(db.Integer, db.ForeignKey('talentpref.id'))
talentpref3_id = db.Column(db.Integer, db.ForeignKey('talentpref.id'))
talentpref1 = db.relationship("TalentPref", uselist=False, foreign_keys=talentpref1_id)
talentpref2 = db.relationship("TalentPref", uselist=False, foreign_keys=talentpref2_id)
talentpref3 = db.relationship("TalentPref", uselist=False, foreign_keys=talentpref3_id)
Run Code Online (Sandbox Code Playgroud)
我正在使用 flask-restless 将调度模型作为 api 资源提供服务。当我按计划执行查询并要求按 Talentpref1__lastName 对查询进行排序时,我收到一个错误,该错误与我有多个引用“TalentPref”表的实例有关:
我可以在 id 列上成功使用查询字符串,如下所示:
/api/schedule?id=id&page=1&q={"order_by":[{"field":"id","direction":"desc"}]}
Run Code Online (Sandbox Code Playgroud)
但是使用以下 http GET 查询字符串的查询失败:
/api/schedule?id=id&page=1&q={"order_by":[{"field":"talentpref1__lastName","direction":"desc"}]}
Run Code Online (Sandbox Code Playgroud)
和:
Traceback (most recent call last):
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/flask_restless/views.py", line 1172, in _search
result = search(self.session, self.model, search_params)
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/flask_restless/search.py", line 587, in search
query = create_query(session, model, search_params, _ignore_order_by)
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/flask_restless/search.py", line 549, in create_query
_ignore_order_by)
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/flask_restless/search.py", line 498, in create_query
query = query.join(relation_model)
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 1971, in join
from_joinpoint=from_joinpoint)
File "<string>", line 2, in _join
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/sqlalchemy/orm/base.py", line 201, in generate
fn(self, *args[1:], **kw)
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2115, in _join
outerjoin, full, create_aliases, prop)
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2188, in _join_left_to_right
self._join_to_left(l_info, left, right, onclause, outerjoin, full)
File "/Users/myuser/Documents/pythonenvironments/venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2317, 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.model.TalentPref'>, but got: Can't determine
join between 'schedule' and 'talentpref'; tables have more than one
foreign key constraint relationship between them. Please specify the
'onclause' of this join explicitly.
Run Code Online (Sandbox Code Playgroud)
有没有办法可以成功查询这种关系?
这似乎是flask-restless本身的限制。当传递一个<字段名>的形式的<relationname> __ <字段名>它将分割名称,并使用第一部分作为关系。它使用关系属性来查找要加入的相关模型类:
if '__' in field_name:
field_name, field_name_in_relation = \
field_name.split('__')
relation = getattr(model, field_name)
relation_model = relation.mapper.class_
field = getattr(relation_model, field_name_in_relation)
direction = getattr(field, val.direction)
query = query.join(relation_model)
# ^^^^^^^^^^^^^^ TalentPref model class
query = query.order_by(direction())
Run Code Online (Sandbox Code Playgroud)
https://github.com/jfinkels/flask-restless/blob/0.17.0/flask_restless/search.py#L498
在你的情况下,这是有效的
query = query.join(TalentPref)
Run Code Online (Sandbox Code Playgroud)
并且由于您有多个连接路径,SQLAlchemy 无法确定要做什么。如果flask-restless 要么使用简单的关系连接而不是连接目标实体,要么将relationship()-driven ON 子句调整为目标实体,这将不是问题。
你可以修补你的flask-restless来修复这个特定的查询:
--- search.py 2017-03-29 09:56:00.439981932 +0300
+++ search_joinfix.py 2017-03-29 09:56:41.375851375 +0300
@@ -495,7 +495,7 @@
relation_model = relation.mapper.class_
field = getattr(relation_model, field_name_in_relation)
direction = getattr(field, val.direction)
- query = query.join(relation_model)
+ query = query.join(relation)
query = query.order_by(direction())
else:
field = getattr(model, val.field)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3401 次 |
| 最近记录: |