Python SQLAlchemy ORM:在INSERT语句中使用VALUES参数和内联SELECT
我想使用SQLAlchemy ORM进行插入,使用依赖于其他值之一的内联select语句查找默认值。例如:Python SQLAlchemy ORM:在INSERT语句中使用VALUES参数和内联SELECT,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我想使用SQLAlchemy ORM进行插入,使用依赖于其他值之一的内联select语句查找默认值。例如: INSERT INTO foo (template_id, bar) VALUES (%(template_id)s, (SELECT template.bar_default FROM template WHERE template.id = %(template_id)s)) RE
INSERT INTO foo (template_id, bar)
VALUES (%(template_id)s,
(SELECT template.bar_default
FROM template
WHERE template.id = %(template_id)s))
RETURNING foo.id
例如select()
,因此我考虑将其设置为:select([Template.bar\u default])。其中(Template.id==bindparam('Template\u id')
,如下所示:
class Template(sa.Model):
id = sa.Column(sa.Integer, primary_key=True)
bar_default = sa.Column(sa.String(20))
class Foo(sa.Model):
id = sa.Column(sa.Integer, primary_key=True)
template_id = sa.Column(sa.Integer, sa.ForeignKey(Template.id))
bar = sa.Column(sa.String(20),
default=select([Template.bar_default])
.where(Template.id == bindparam('template_id'))))
但是,此方法不起作用。它失败,但出现以下例外情况:
sqlalchemy.exc.CompileError:bindparam()名称“template_id”为
保留用于此文件的VALUES或SET子句中的自动使用
insert/update语句。请使用列名以外的名称
将bindparam()与insert()或update()一起使用时(例如,
“b_模板_id”)
bindparam()
拒绝允许从值中重新使用名称,尽管这正是我在这里需要的。有没有办法避免异常
@lrnzcig建议的我目前的解决方法:
def before_insert_listener(mapper, connection, target):
if target.template_id and not target.bar:
target.bar = select([Template.bar_default])\
.where(Template.id == target.template_id)
event.listen(Foo, 'before_insert', before_insert_listener)
老实说,我不知道为什么会发生这种情况。可能无法预见
default
值和bindparam
的组合?您是否尝试过使用正常的insert-select
语句来实现这一点?即使用select
作为insert
的值。使用insert-select应该没有问题de>@lrnzcig这并不理想,因为select语句需要在insert之前手动生成——但它可以工作,我现在就用它,所以谢谢!为什么要手动?我想你应该可以用子查询来完成。无论如何,很高兴它能帮上忙。@lrnzig我的意思是,如果我不能绑定到父查询的参数,我必须手动生成子查询。老实说,我不知道为什么会发生这种情况。可能无法预见default
值和bindparam
的组合?您是否尝试过使用正常的insert-select
语句来实现这一点?即使用select
作为insert
的值。使用insert-select应该没有问题de>@lrnzcig这并不理想,因为select语句需要在insert之前手动生成——但它可以工作,我现在就用它,所以谢谢!为什么要手动?我想你应该可以用子查询来完成。无论如何,很高兴它能帮上忙。@lrnzig我的意思是,如果我不能绑定到父查询的参数,我必须手动生成子查询。老实说,我不知道为什么会发生这种情况。可能无法预见default
值和bindparam
的组合?您是否尝试过使用正常的insert-select
语句来实现这一点?即使用select
作为insert
的值。使用insert-select应该没有问题de>@lrnzcig这并不理想,因为select语句需要在insert之前手动生成——但它可以工作,我现在就用它,所以谢谢!为什么要手动?我想你应该可以用子查询来完成。无论如何,很高兴它能帮上忙。@lrnzig我的意思是,如果我不能绑定到父查询的参数,我必须手动生成子查询。