我有两张表table_a
和table_b
。 table_b.code_b
是table_a
table_a
code_a, val
-----------
aaa,100
table_b
code_b, name
------------
aaa, name1
我希望通过加入两个表来获得此结果:
table_result
code_a,val,name
---------------
aaa,100,name1
以下是Python代码:
class A(db.Model):
__tablename__ = 'table_a'
code_a = Column(String(20), ForeignKey("table_b.code_b"), primary_key=True)
val = Column(Float)
b = relationship("B", backref=backref('table_b'))
class B(db.Model):
__tablename__ = 'table_b'
code_b = Column(String(20), primary_key=True)
name = Column(String(100))
a = relationship("A", backref="table_a")
where_str = "code_b='aaa'"
q = A.query.options(joinedload_all(A.b)).filter(text(where_str))
rows1 = [i.serialize for i in q.all()] # CORRECT
rows2 = [i.serialize for i in q.paginate(1,10,False)] # ERROR
如果我只是查询全部来获取rows1
,那么结果是正确的。但是,运行rows2
时会出错:
DatabaseError:(cx_Oracle.DatabaseError)ORA-00904:“code_b”
我通过打印SQL语句来调试此错误:
SELECT count(*) AS count_1
FROM (SELECT "table_a".code_a AS "table_a_code_a",
FROM "table_a"
WHERE code_b = 'aaa') anon_1
很明显,两个表 NOT 已加入。
但是,如果只是q.all()
,SQL语句将是:
SELECT "table_a".code_a AS "table_a_code_a",
FROM "table_a" LEFT JOIN "table_b"
WHERE code_b = 'aaa'
这是正确的。
那么,如何在制作分页时获得正确的结果。
EDIT1:
问:为什么我使用where_str
?
答:在HTML页面中,我使用查询构建器(http://querybuilder.js.org/)来获取查询过滤器(可能很复杂)。因此,传递给SQLAlchemy查询文件管理器很方便。
有更好的方法来实现这个吗?
EDIT2: 解决方案:
q = A.query.join(A.b).options(contains_eager(A.b)).filter(text(where_str))
答案 0 :(得分:1)
这是不正确的:
where_str = "code_b='aaa'"
q = A.query.options(joinedload_all(A.b)).filter(text(where_str))
SQLAlchemy如何知道code_b
中的where_str
应该引用表B?
尝试:
q = A.query.join(A.b).filter(B.code_b == "aaa")
如果您还需要执行joinedload
,请执行以下操作:
q = A.query.join(A.b).options(contains_eager(A.b)).filter(B.code_b == "aaa")