4

我一直在研究如何将具有 7 个元素(列)的约 500 个元组(行)的列表插入到数据库中。我已经阅读了关于 stackoverflow 以及其他论坛的各种帖子。我发现了以下内容,它建议使用“executemany()”方法,但我不太清楚如何使用。我需要将我的对象从元组转换为字典吗?问题是我没有名称:数据结构的值类型。

如何使用 SQLAlchemy 将 SQL 文件从查询表达式转储到批量插入 DBMS?

Here is an example:

engine = create_engine('sqlite:///:memory:', echo=True)
metadata = MetaData()
hockey= Table('hockey', metadata, 
    Column('team', String(16), primary_key=True),
    Column('jersey_colour', String(16)),
    Column('stadium', String(32)),
    Column('goals', Integer),
    Column('date', Date, primary_key=True),
    Column('assists', Integer))

>>>data[0]
[(u'Maple Leafs', u'Blue', u'Air Canada Center', 151, '2013-03-25', 301)]

编辑:

我尝试了描述的解决方案(Sqlalchemy 核心,从元组插入多行而不是 dict)如下:

markers = ','.join('?' * len(data[0]))
ins = 'INSERT INTO {tablename} VALUES ({markers})'
ins = ins.format(tablename=hockey.name, markers=markers)

>>str(ins)
'INSERT INTO hockey VALUES (?,?,?,?,?,?)'

conn = engine.connect()
result = conn.execute(ins, data)

In [59]: result = conn.execute(ins, data)
2013-03-26 07:29:28,371 INFO sqlalchemy.engine.base.Engine INSERT INTO hockey VALUES (?,?,?,?,?,?)
2013-03-26 07:29:28,371 INFO sqlalchemy.engine.base.Engine (u'Maple Leafs', u'Blue', u'Air Canada Center', 151, '2013-03-25', 301)
2013-03-26 07:29:28,371 INFO sqlalchemy.engine.base.Engine ROLLBACK
---------------------------------------------------------------------------
OperationalError                          Traceback (most recent call last)
<ipython-input-59-dafe2aef2c66> in <module>()
----> 1 result = conn.execute(ins, data)

/usr/lib/python2.7/site-packages/sqlalchemy/engine/base.pyc in execute(self, object, *multiparams, **params)
    662                                                 object,
    663                                                 multiparams,
--> 664                                                 params)
    665         else:
    666             raise exc.InvalidRequestError(

/usr/lib/python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_text(self, statement, multiparams, params)
    806             statement,
    807             parameters,
--> 808             statement, parameters
    809         )
    810         if self._has_events:

/usr/lib/python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
    876                                 parameters,
    877                                 cursor,
--> 878                                 context)
    879             raise
    880

/usr/lib/python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
    869                                     statement,
    870                                     parameters,
--> 871                                     context)
    872         except Exception, e:
    873             self._handle_dbapi_exception(

/usr/lib/python2.7/site-packages/sqlalchemy/engine/default.pyc in do_execute(self, cursor, statement, parameters, context)
    318
    319     def do_execute(self, cursor, statement, parameters, context=None):
--> 320         cursor.execute(statement, parameters)
    321
    322     def do_execute_no_params(self, cursor, statement, context=None):

OperationalError: (OperationalError) near "hockey": syntax error 'INSERT INTO hockey VALUES (?,?,?,?,?,?)' (u'Maple Leafs', u'Blue', u'Air Canada Center', 151, '2013-03-25', 301)

有错误:

  OperationalError: (OperationalError) near "hockey": syntax error 'INSERT INTO hockey VALUES (?,?,?,?,?,?)' (u'Maple Leafs', u'Blue', u'Air Canada Center', 151, '2013-03-25', 301)
4

2 回答 2

2

好吧,我做了以下事情:

column_names = tuple(c.name for c in hockey.c)

>>>column_names
('team', 'jersey_colour', 'stadium', 'goals', 'date', 'assists')

final = [dict(zip(column_names,x)) for x in data]

上面为每一行或每一行创建了一个字典列表。这应该可以,但是当我运行时出现以下错误:

>>>conn.execute(ins, final)

SQLite Date type only accepts Python date objects as input.

无论如何,这是我需要研究的另一个问题。也就是说,我正在回答并接受这个问题,因为上面的字典应该可以工作。

于 2013-03-26T17:40:22.470 回答
0

来自未来的你好!

我发现自己想基于现有的 SQLAlchemy 表(或模型,declarative_base()在我的情况下继承自)进行批量数据插入。我也对必须即时创建字典来进行插入的想法感到恼火,并寻找一种更直接的方法。

我敢肯定,自从您在 2013 年问/回答这个问题以来,发生了很多变化,但是在 2021 年,使用 SQLAlchemy 1.4 和 Python 3.7.something,这对我有用:

from sqlalchemy import create_engine, MetaData, Table, Column, String, Integer

engine = create_engine('sqlite:///:memory:', echo=True)
metadata = MetaData(bind=engine)

hockey = Table('hockey', metadata, 
    Column('team', String(16), primary_key=True),
    Column('jersey_colour', String(16)),
    Column('stadium', String(32)),
    Column('goals', Integer),
    Column('date', String(10), primary_key=True),
    Column('assists', Integer))

data = [
    ['Blue', 'Toronto Maple Leafs', 'Air Canada Center', '2013-03-25', 301, 151], 
    ['Red', 'Calgary Flames', 'PenWest', '2013-03-25', 254, 147]
]

metadata.create_all()
engine.execute(hockey.insert().values(data))

您可能会注意到date,为简单起见,我将字段更改为字符串,因为 SQLite DB-API 库需要 Pythondatetime.date用于此处所述的那些。(任何对这种小把戏感到困惑的人都应该看到这个答案以获得澄清。)

无论如何,现在使用将二维数据结构插入 SQLite 数据库可以.insert().values正常工作,而无需dict(zip(…))繁琐。

>>> from sqlalchemy import select
>>> engine.execute(select(hockey)).all()

[('Blue', 'Toronto Maple Leafs', 'Air Canada Center', '2013-03-25', '301', 151),
 ('Red', 'Calgary Flames', 'PenWest', '2013-03-25', '254', 147)]
于 2021-12-30T22:51:05.887 回答