使用SQLAlchemy核心(而不是ORM),我想要在值中使用子查询插入多行。对于MySQL,实际的SQL会是这个样子:如何使用SQLAlchemy Core在子查询中插入多个值?
INSERT INTO widgets (name, type) VALUES
('Melon', (SELECT type FROM widgetTypes WHERE type='Squidgy')),
('Durian', (SELECT type FROM widgetTypes WHERE type='Spiky'))
但我只似乎能够使用上insert()
条款,只允许我做一次一个刀片的values()
方法时要使用子查询。我希望一次插入多个值,将它们全部作为绑定参数列表传递给Connection
的execute()
方法,但似乎不支持。
是否可以在的单个调用中执行我想要的操作?
这是一个独立的演示。请注意,这使用了sqlite引擎,其中doesn't support multiple inserts in the same way as MySQL,但SQLAlchemy代码仍然以与真正的MySQL应用程序相同的方式失败。
from sqlalchemy import *
if __name__ == "__main__":
# Construct database
metadata = MetaData()
widgetTypes = Table('widgetTypes', metadata,
Column('id', INTEGER(), primary_key=True),
Column('type', VARCHAR(), nullable=False),
)
widgets = Table('widgets', metadata,
Column('id', INTEGER(), primary_key=True),
Column('name', VARCHAR(), nullable=False),
Column('type', INTEGER(), nullable=False),
ForeignKeyConstraint(['type'], ['widgetTypes.id']),
)
engine = create_engine("sqlite://")
metadata.create_all(engine)
# Connect and populate db for testing
conn = engine.connect()
conn.execute(widgetTypes.insert(), [
{'type': 'Spiky'},
{'type': 'Squidgy'},
])
# Some select queries for later use.
select_squidgy_id = select([widgetTypes.c.id]).where(
widgetTypes.c['type']=='Squidgy'
).limit(1)
select_spiky_id = select([widgetTypes.c.id]).where(
widgetTypes.c['type']=='Squidgy'
).limit(1)
# One at a time works via values()
conn.execute(widgets.insert().values(
{'name': 'Tomato', 'type': select_squidgy_id},
))
# And multiple values work if we avoid subqueries
conn.execute(
widgets.insert(),
{'name': 'Melon', 'type': 2},
{'name': 'Durian', 'type': 1},
)
# Check above inserts did actually work
print conn.execute(widgets.select()).fetchall()
# But attempting to insert many at once with subqueries does not work.
conn.execute(
widgets.insert(),
{'name': 'Raspberry', 'type': select_squidgy_id},
{'name': 'Lychee', 'type': select_spiky_id},
)
运行它,它死在最后通话用:
sqlalchemy.exc.InterfaceError: (InterfaceError) Error binding parameter 1 - probably unsupported type. u'INSERT INTO widgets (name, type) VALUES (?, ?)' (('Raspberry', <sqlalchemy.sql.expression.Select at 0x19f14d0; Select object>), ('Lychee', <sqlalchemy.sql.expression.Select at 0x19f1a50; Select object>))
我有一种直觉,认为你做错了 - 目前你想为每一条记录执行一个子查询。而且由于您使用的是SQLAlchemy Core,这意味着所有的SQL都会按照您提供的那样执行。 – plaes
@plaes yep这正是我想要做的(对每条记录执行一个子查询),你只需要相信我在真实应用程序':)'中更有意义。但问题是,SQLAlchemy **不是正在执行我正在执行的内容,而是拒绝处理'Select'表达式':(' – Day