我有 2D 元组中的数据(或者说来自 Numpy 表),并且需要将其插入到 SQL 表中。将 Sqlalchemy Core 与 SQLite 结合使用,如何高效、简单地将这些数据插入到我的表中?
取自@eclaird;
engine = sa.create_engine('sqlite://', echo=True)
metadata = sa.MetaData()
widgets_table = sa.Table('widgets', metadata,
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('bar', sa.String(50)),
sa.Column('biz', sa.Boolean),
sa.Column('baz', sa.Integer),
)
metadata.create_all(engine)
# Assuming this is the data where None holds place for primary key
my_data = [
(None, "Test", True, 3),
(None, "Test", True, 3),
]
到目前为止,我在文档中处于这一点;所以我有;
engine.execute(widgets_table.insert().values((None, "Test", True, 3)))
这有效。但我想一次插入多行,例如
engine.execute(widgets_table.insert().values(((None, "Test", True, 3), (None, "Test", True, 3))))
但是随后出错;
当前数据库版本设置的“sqlite”方言不支持就地多行插入。
也尝试过;
insert = widgets_table.insert()
engine.execute(insert, [
(None, "Test", True, 3),
(None, "Test", True, 3)
])
有错误;
属性错误:“元组”对象没有属性“键”
作为最近转向 SQLalch 的人,我在这里有点迷失。
您缺少一些有关设置的详细信息,因此我弥补了一些内容。插入元组很困难,除非您也插入表的主键,那么为什么不在插入之前从数据创建字典呢?
这应该适用于 SQLAlchemy 0.7.6 及更高版本:
import sqlalchemy as sa
engine = sa.create_engine('sqlite://', echo=True)
metadata = sa.MetaData()
widgets_table = sa.Table('widgets', metadata,
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('foo', sa.String(50)),
sa.Column('bar', sa.String(50)),
sa.Column('biz', sa.Boolean),
sa.Column('baz', sa.Integer),
)
metadata.create_all(engine)
# Assuming this is your data
values = [
(None, "Test", True, 3),
(None, "Test", True, 3),
]
with engine.connect() as connection:
with connection.begin() as transaction:
try:
markers = ','.join('?' * len(values[0]))
ins = 'INSERT INTO {tablename} VALUES ({markers})'
ins = ins.format(tablename=widgets_table.name, markers=markers)
connection.execute(ins, values)
except:
transaction.rollback()
raise
else:
transaction.commit()
来自未来的你好!
如评论中所述,此解决方案使用对象关系映射器而不是SQLAlchemy Core。当我最初发布这个答案时,我没有注意到这个规定。
也就是说,如果您可以在使用 ORM 方面做出妥协,那么现在(以 SQLAlchemy 1.4 和 2.0 为标准)您最初在列表或元组列表上使用
insert().values
的尝试应该可以正常工作。
目前我还没有太多使用 SQLAlchemy 的经验,所以我不能正确地说出发生了什么变化。也许变化不是在 SQLAlchemy 中,而是在 Python 附带的
sqlite3
DB-API 库中。我应该注意,在这种情况下,我使用的是 Python 3.7.12。
import sqlalchemy as sa
engine = sa.create_engine('sqlite://', echo=True)
metadata = sa.MetaData()
widgets_table = sa.Table('widgets', metadata,
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('bar', sa.String(50)),
sa.Column('biz', sa.Boolean),
sa.Column('baz', sa.Integer),
)
metadata.create_all(engine)
my_data = [
(None, "Test", True, 3),
(None, "Test", True, 3),
]
# works fine
engine.execute(widgets_table.insert().values(my_data))
然后:
>>> engine.execute(sa.select(widgets_table)).all()
[(1, 'Test', True, 3), (2, 'Test', True, 3)]