Using SQLAlchemy Core (not ORM), I am trying to Insert multiple rows using subqueries in values. For MySQL, the actual SQL would look something like this:
INSERT INTO widgets (name, type) VALUES
('Melon', (SELECT type FROM widgetTypes WHERE type='Squidgy')),
('Durian', (SELECT type FROM widgetTypes WHERE type='Spiky'))
But it seems to me that I can use subqueries when using the values()on method insert(), which allows me to do only one insert at a time. I would like to insert several values โโat once, passing them to the whole method Connection execute()as a list of binding parameters, but this does not seem to be supported.
Is it possible to do what I want in one call execute()?
There is a self-sufficient demonstration here. Note that this uses the sqlite mechanism, which does not support multiple attachments in the same way as MySQL , but the SQLAlchemy code still does not work the same as the actual MySQL application.
from sqlalchemy import *
if __name__ == "__main__":
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)
conn = engine.connect()
conn.execute(widgetTypes.insert(), [
{'type': 'Spiky'},
{'type': 'Squidgy'},
])
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)
conn.execute(widgets.insert().values(
{'name': 'Tomato', 'type': select_squidgy_id},
))
conn.execute(
widgets.insert(),
{'name': 'Melon', 'type': 2},
{'name': 'Durian', 'type': 1},
)
print conn.execute(widgets.select()).fetchall()
conn.execute(
widgets.insert(),
{'name': 'Raspberry', 'type': select_squidgy_id},
{'name': 'Lychee', 'type': select_spiky_id},
)
Run it and it will die on the last call execute()with:
sqlalchemy.exc.InterfaceError: (InterfaceError) Binding error parameter 1 - possibly an unsupported type. u'INSERT INTO widgets (name, type) VALUES (?,?) '(("Raspberry", <sqlalchemy.sql.expression.Select at 0x19f14d0; Select an object>), (' Lychee ', <sqlalchemy.sql.expression .Select at 0x19f1a50; Select an object>))