Al usar SQLAlchemy Core (no ORM), intento INTRODUCIR varias filas usando subconsultas en los valores. Para MySQL, el SQL real sería algo como esto:¿Cómo insertar valores múltiples con subconsulta con SQLAlchemy Core?
INSERT INTO widgets (name, type) VALUES
('Melon', (SELECT type FROM widgetTypes WHERE type='Squidgy')),
('Durian', (SELECT type FROM widgetTypes WHERE type='Spiky'))
Pero sólo parece ser capaz de utilizar subconsultas cuando se utiliza el método de values()
en una cláusula insert()
que sólo me permite hacer una inserción en un momento. Me gustaría insertar varios valores a la vez pasándolos todos al método Connection
execute()
como una lista de parámetros de enlace, pero esto no parece ser compatible.
¿Es posible hacer lo que quiero en una sola llamada al execute()
?
Aquí hay una demostración independiente. Tenga en cuenta que utiliza el motor sqlite que doesn't support multiple inserts in the same way as MySQL, pero el código SQLAlchemy sigue fallando de la misma manera que la aplicación MySQL real.
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},
)
Ejecutar y muere en el último execute()
llamada con:
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>))
Tengo la intuición de que lo estás haciendo mal: actualmente quieres ejecutar una subconsulta para cada registro. Y debido a que está utilizando SQLAlchemy Core, significa que todo el SQL se ejecutará exactamente como lo suministra. – plaes
@plaes yep eso es exactamente lo que quiero hacer (ejecutar una subconsulta para cada registro), solo tendrá que confiar en mí que tiene más sentido en la aplicación real ':)'. Pero el problema es que SQLAlchemy ** no está ** ejecutando exactamente lo que yo proporciono, y se niega a procesar la expresión 'Seleccionar'': (' – Day