【发布时间】:2021-08-30 19:18:06
【问题描述】:
我在将工作 SQL 文本转换为 ORM 命令时遇到问题...
select ctx_j.name as cat_name, x.id as value_id, x.value_r1 as r1,
x.value_r2 as r2, x.value_r3 as r3, x.value_r4 as r4
from (
select cv.id as id, cs.name as name
from context_values cv
left join context_categories cs
on cv.cat_id=cs.id
where cv.verified is True
) as ctx_j
left join (
select t3.id as id, value_r1, value_r2, value_r3, value_r4
from (((((
context_values as v
left join context_value_r1 as r1 on v.id=r1.value_id) as t1
left join context_value_r2 as r2 on t1.id=r2.value_id) as t2
left join context_value_r3 as r3 on t2.id=r3.value_id) as t3
left join context_value_r4 as r4 on t3.id=r4.value_id
) as x on ctx_j.id=x.id
order by cat_name, value_id
来自以下模型:
class Context_value(db.Model):
__tablename__ = 'context_values'
id = db.Column(...)
cat_id = db.Column(db.SmallInteger, db.ForeignKey('context_categories.id',
ondelete="RESTRICT", onupdate="CASCADE"), unique=False, index=True, nullable=False)
verified = db.Column(db.Boolean)
context_value_r1 = db.relationship('Context_value_r1', backref='context_values', lazy='dynamic')
etc.
class Context_category(db.Model):
__tablename__ = 'context_categories'
id = db.Column(db.SmallInteger, primary_key=True)
...
name = db.Column(db.String(100), nullable=False)
__table_args__ = (db.Index('unq_context_categories_name', '...', 'name', unique=True),)
ctx_values = db.relationship('Context_value', backref='context_categories', lazy='select')
SQL 命令在 DB 管理空间中完成其预期的工作(在物化视图中组合相关值以便快速查找),但我在 ORM 语法中找不到合适的表示。
db.join(
db.select(Context_category).
outerjoin(Context_category.ctx_values).
where(Context_value.verified==True
),
db.select(Context_value).
outerjoin(Context_value.context_rel1).
outerjoin(Context_value.context_rel2).
outerjoin(Context_value.context_rel3).
outerjoin(Context_value.context_rel4).
all(),
isouter=True
)
产生以下错误(仅限消息的结尾):
File "c:\users\...\app\models\mod_context.py", line 638, in ...
db.select(Context_category).\
File "<string>", line 2, in select
File "<string>", line 2, in __init__
File "c:\users\...\venv\lib\site-packages\sqlalchemy\util\deprecations.py", line 139, in warned
return fn(*args, **kwargs)
File "c:\users\...\venv\lib\site-packages\sqlalchemy\sql\selectable.py", line 3114, in __init__
for c in columns:
TypeError: 'DefaultMeta' object is not iterable
任何帮助或建议将不胜感激。
【问题讨论】:
-
从您加入的查询中删除
.all()。 -
我试过了,但这会导致另一个问题:
File "c:\users\...\app\models\mod_context.py", line 641, in ... db.select(Context_category). File "<string>", line 2, in select File "<string>", line 2, in __init__ File "c:\users\...\venv\lib\site-packages\sqlalchemy\util\deprecations.py", line 139, in warned return fn(*args, **kwargs) File "c:\users\...\venv\lib\site-packages\sqlalchemy\sql\selectable.py", line 3114, in __init__ for c in columns: TypeError: 'DefaultMeta' object is not iterable -
这看起来仍然是同样的错误
-
抱歉,是的,同样的问题 - 我在想别的东西。基本上,它不能识别 Context_category 模型中的列。通过在原始 SQL 中显式指定列很容易避免此问题。
标签: python postgresql sqlalchemy orm flask-sqlalchemy