How to insert multiple values with subquery using SQLAlchemy Core?
使用SQLAlchemy Core(不是ORM),我正在尝试使用值中的子查询来插入多行。对于MySQL,实际的SQL如下所示:
1 2 3 | INSERT INTO widgets (name, type) VALUES ('Melon', (SELECT type FROM widgetTypes WHERE type='Squidgy')), ('Durian', (SELECT type FROM widgetTypes WHERE type='Spiky')) |
但是在
是否可以在一次调用
这是一个自成一体的示范。请注意,这使用了sqlite引擎,该引擎不支持与MySQL相同的方式进行多次插入,但是SQLAlchemy代码仍然以与真实MySQL应用程序相同的方式失败。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 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',), ('Lychee',
))
您必须将其嵌入INSERT语句中,而不是提供subselect语句作为参数值:
1 2 3 4 5 6 7 8 9 | type_select = select([widgetTypes.c.id]).where( widgetTypes.c.type==bindparam('type_name')) insert = widgets.insert({'type': type_select}) conn.execute(insert, [ {'name': 'Melon', 'type_name': 'Squidgy'}, {'name': 'Lychee', 'type_name': 'Spiky'}, ]) |