使用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