【发布时间】:2020-10-09 07:12:42
【问题描述】:
我在falsk-sqlalchemy 中有以下模型/表格:
class MainTerm(db.Model):
__tablename__ = 'main_term'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String)
terms_in_gzt = db.Table('terms_in_gzt',
db.Column('gzt_term_id', db.Integer, db.ForeignKey('gzt_term.id')),
db.Column('gazetteer_id', db.Integer, db.ForeignKey('gazetteer.id')),
)
class Gazetteer(db.Model):
__tablename__ = 'gazetteer'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
terms = db.relationship('GztTerm', secondary=terms_in_gzt, backref='gazetteers', lazy='dynamic')
class GztTerm(db.Model):
__tablename__ = 'gzt_term'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String)
我目前正在运行 sqlite(sqlite 版本 '3.32.3'),但后来打算使用 postgresql。因此,postgres 的解决方案比 sqlite 的解决方案更重要。
我有这个连接查询来查询与Gazetteer.id == 3 关联的GztTerm 条目的text 列:
joinq = db.session.query(GztTerm.text).join(terms_in_gzt).join(Gazetteer).filter(Gazetteer.id == 3)
joinq.all()
结果如下:
[('IBM'), ('Lund'), ('Bluetooth')]
当我现在打电话时:
binary_expression = MainTerm.text.contains(joinq)
res = db.session.query(MainTerm).filter(binary_expression).all()
然后我只得到第一个元素 “IBM” 的结果。 "Bluetooth" 或 "Lund" 的结果缺失,即使它们在数据库中。当我更改查询时,我总是只得到joinq 的第一个元素的结果。
所以我的问题是:
我需要改变什么,我的BinaryExpression MainTerm.text.contains(joinq) 考虑了joinq 的所有元素?
提前致谢!
编辑:
以下用于构造 binary_expression 的代码归档了所需的行为:
from sqlalchemy import or_
binary_expression = or_(MainTerm.text.contains(text) for text in joinq)
不过,这感觉更像是一种 hack,而且可能效率不高。
有没有办法仅使用 sqlalchemy 来归档相同的行为而无需循环? em>
【问题讨论】:
-
你用的是什么数据库?
-
打印查询本身,您可能会发现它生成 SQL 代码的两种方式存在差异
-
@IljaEverilä 我正在使用 sqlite 版本“3.32.3”。这对其他数据库会有所不同吗?
-
@Peter 打印出来到底是什么意思?
-
如
query = db.session.query(MainTerm).filter(binary_expression); result = query.all()。您可以打印查询对象以查看其背后的原始 SQL。
标签: python sqlalchemy flask-sqlalchemy