sqlalchemy joinedload查询无法统计

时间:2016-05-06 02:10:30

标签: python sqlalchemy flask-sqlalchemy

我有两张表table_atable_btable_b.code_btable_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))

1 个答案:

答案 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")
相关问题