Sqlalchemy核心,从元组而不是dict插入多行

Mar*_*nes 5 python sqlite sqlalchemy

我有2D元组中的数据(或者说来自Numpy表),需要将其插入到SQL表中.使用Sqlalchemy Core和SQLite,如何有效地将这些数据插入到我的表中?

来自@eclaird的ie;

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),
    ]
Run Code Online (Sandbox Code Playgroud)

到目前为止,我正处于文档的这一点 ; 所以我有;

engine.execute(widgets_table.insert().values((None, "Test", True, 3)))
Run Code Online (Sandbox Code Playgroud)

哪个有效.但我想一次插入许多行,如

engine.execute(widgets_table.insert().values(((None, "Test", True, 3), (None, "Test", True, 3))))
Run Code Online (Sandbox Code Playgroud)

但那么错误;

具有当前数据库版本设置的'sqlite'方言不支持就地多行插入.

也试过;

insert = widgets_table.insert()

engine.execute(insert, [
                    (None, "Test", True, 3), 
                    (None, "Test", True, 3) 
                    ])
Run Code Online (Sandbox Code Playgroud)

有错误;

AttributeError:'tuple'对象没有属性'keys'

作为最近转换为SQLalch,我在这里有点迷失.

The*_*des 6

你好,来自未来!

\n

到 2021 年,随着 SQLAlchemy 1.4 成为稳定版本,2.0 即将推出,您insert().values在列表(或元组)列表上使用的最初尝试应该可以正常工作。

\n

我对 SQLAlchemy 也比较陌生,所以我不能正确地说出改变了什么\xe2\x80\x94,也许改变不是在 SQLAlchemy 中,而是在sqlite3Python 附带的 DB-API 库中。我应该注意,在这种情况下,我正在使用 Python 3.7.12。

\n
import sqlalchemy as sa\n\nengine = sa.create_engine(\'sqlite://\', echo=True)\nmetadata = sa.MetaData()\n\nwidgets_table = sa.Table(\'widgets\', metadata,\n    sa.Column(\'id\', sa.Integer, primary_key=True),\n    sa.Column(\'bar\', sa.String(50)),\n    sa.Column(\'biz\', sa.Boolean),\n    sa.Column(\'baz\', sa.Integer),\n)\n\nmetadata.create_all(engine)\n\nmy_data = [\n    (None, "Test", True, 3),\n    (None, "Test", True, 3),\n]\n\n# works fine\nengine.execute(widgets_table.insert().values(my_data))\n
Run Code Online (Sandbox Code Playgroud)\n

进而:

\n
>>> engine.execute(sa.select(widgets_table)).all()\n[(1, \'Test\', True, 3), (2, \'Test\', True, 3)]\n
Run Code Online (Sandbox Code Playgroud)\n
\n

另请参阅:python sqlalchemy 在元组数据结构中插入多行

\n


tuo*_*mur 5

您缺少一些有关设置的详细信息,因此我弥补了一些内容。插入元组很困难,除非您也插入表的主键,那么为什么不在插入之前从数据创建字典呢?

这应该适用于 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()
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但我希望避免创建临时字典 - 我想避免必须记住代码中各处的列名称。当我已经拥有二维元组中的数据时,创建这个字典不是多余的吗?但是假设我只知道列的数据类型和顺序,是否有一种简单的方法可以按位置插入它? (3认同)
  • 您需要将字符串 INSERT 语句与“?”结合使用 对于参数,它更直接地发送到 pysqlite DBAPI。无论如何,SQLA insert() 构造总是在内部将事物视为字典。如果性能是目标,那么就需要直接 DBAPI 访问。如果是可移植性,那么只需使用像“dict(zip(((c.key for c in table.c), row))”这样的函数来创建字典。 (2认同)