Korzystanie z SQLAlchemy Core (nie ORM), próbuję INSERT wielu wierszy przy użyciu podzapytania w wartości. MySQL, rzeczywista SQL będzie wyglądać mniej więcej tak:Jak wstawić wiele wartości z podzapytaniem za pomocą SQLAlchemy Core?
INSERT INTO widgets (name, type) VALUES
('Melon', (SELECT type FROM widgetTypes WHERE type='Squidgy')),
('Durian', (SELECT type FROM widgetTypes WHERE type='Spiky'))
Ale tylko wydaje się być w stanie wykorzystać podzapytania przy użyciu metody values()
na insert()
klauzuli, która pozwala tylko mi zrobić jedną wkładkę naraz. Chciałbym wstawić wiele wartości naraz, przekazując je wszystkie do metody Connection
's jako execute()
jako listę parametrów wiązania, ale to nie wydaje się być obsługiwane.
Czy można zrobić to, co chcę, w jednym połączeniu z numerem execute()
?
Oto niezależna demonstracja. Zauważ, że wykorzystuje to silnik sqlite, który jest doesn't support multiple inserts in the same way as MySQL, ale kod SQLAlchemy nadal kończy się niepowodzeniem w ten sam sposób, co prawdziwa aplikacja 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},
)
uruchom go i umiera na ostatniej execute()
rozmowy z:
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>))
Mam przeczucie, że robisz to źle - obecnie chcesz wykonać podzapytanie dla każdego rekordu. A ponieważ używasz SQLAlchemy Core, oznacza to, że wszystkie SQL będą wykonywane dokładnie tak, jak je dostarczasz. – plaes
@plaes yep to dokładnie to, co chcę zrobić (wykonać podzapytanie dla każdego pojedynczego rekordu), musisz tylko zaufać mi, że ma to więcej sensu w prawdziwej aplikacji ':)'. Ale problem polega na tym, że SQLAlchemy ** nie wykonuje ** dokładnie tego, co dostarczam, i odmawia przetworzenia wyrażenia 'Select' expression': (' – Day