连接上带有过滤器的Python SqlAlchemy模型实例返回None类型
我的问题是从连接多对多表中获取模型实例,并通过table1.id和table2.some_字段作为子查询或第二个过滤器对其进行过滤 例如,我有这样的模型:连接上带有过滤器的Python SqlAlchemy模型实例返回None类型,python,database,sqlalchemy,flask-sqlalchemy,Python,Database,Sqlalchemy,Flask Sqlalchemy,我的问题是从连接多对多表中获取模型实例,并通过table1.id和table2.some_字段作为子查询或第二个过滤器对其进行过滤 例如,我有这样的模型: assoc = db.Table('table1_table2', db.Column('table1_id', db.Integer, db.ForeignKey('table1.id')), db.Column('table2_
assoc = db.Table('table1_table2',
db.Column('table1_id', db.Integer, db.ForeignKey('table1.id')),
db.Column('table2_id', db.Integer, db.ForeignKey('table2.id')))
class Table1(db.Models):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
class Table2(db.Models):
id = db.Column(db.Integer, primary_key=True)
some_field = db.Column(db.Boolean)
table1 = db.relationship('Table1', secondary=table1_table2)
基于该代码
instance = db.session.query(Table1).\
join(Table1.table1).\
options(contains_eager(Table1.table1)).\
filter(Table1.name == some_value).\
filter(Table2.somefield == True).\
first()
我收到了Table1
模型实例,但当没有关系发生时
(空的Table2表),我收到的是None
对象。在我的情况下,如何接收instance.table2=[]
以使延迟加载工作
编辑:
我对sqlalchemy查询做了如下更改:
instance = db.session.query(Table1). \
outerjoin(table1_table2). \
outerjoin(Table2, and_(Table2.id == table1_table2.c.table2_id, Table2.some_field = True)). \
filter(Table1.name == some_value). \
first()
这个查询的结果更接近我的期望-当没有关系时,它返回空列表,但当有多个关系时,它返回所有关系,我们的筛选处于联接条件
预期结果:
>>>instance.table2
[<Table2 {id}:True>, <Table2 {id}:True>]
简而言之,使用
outerjoin()
并将Table2
谓词移动到ON子句。Related@IljaEveriläI编辑了我的问题。您正在接近fixed instance None类型,但现在它返回未筛选的table2.some_字段。您遗漏了选项(包含渴望(…)
,因此您正在恢复到新查询中的默认行为。@IljaEverilä在联接之后插入选项(包含渴望(…),我只收到一个table2实例;由于没有关系,我一直没有使用任何类型的table1实例来查看您使用的first()
,它只获取第一行和第一行,因此只接收1Table2
实例是很自然的(它通过使用LIMIT 1
或等效项工作)。而是使用all()
并提取实例。无法再次复制“没有关系,我拥有None
”。
>>>instance.table2
[<Table2 {id}:True>, <Table2 {id}:False>, <Table2 {id}:True>]
instance = db.session.query(Table1). \
filter(Table1.name == some_value). \
outerjoin(table1_table2). \
outerjoin(Table2, and_(Table2.id == table1_table2.c.table2_id, Table2.some_field = True)). \
options(contains_eager(Table1.table2)).\
all()[0]