【问题标题】:python sqlalchemy insert multiple lines in a tuple data structurepython sqlalchemy 在元组数据结构中插入多行
【发布时间】:2013-03-26 02:10:14
【问题描述】:

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

How to use SQLAlchemy to dump an SQL file from query expressions to bulk-insert into a 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 core, insert multiple rows from a tuple instead of 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)

【问题讨论】:

  • 看起来您必须根据教程To issue many inserts using DBAPI’s executemany() method, we can send in a list of dictionaries each containing a distinct set of parameters to be inserted, as we do here to add some email addresses: 提供字典列表。只需将元组转换为字典即可。
  • 感谢 CppLearner。因此,当我将元组转换为 dict 时,key 字段是什么重要吗?关键字段是否必须与表中的列名匹配?感谢你的帮助。谢谢。
  • 是的!字典键的名称应该与数据库中的属性(或字段)名称匹配!所以使用任何你有的列。 T

标签: python sqlalchemy tuples bulkinsert sql-insert


【解决方案1】:

好吧,我做了以下事情:

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.

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

【讨论】:

    【解决方案2】:

    来自未来的你好!

    我发现自己想要基于现有的 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 库需要 Python datetime.date 来表示 here。 (任何对这种小把戏感到困惑的人都应该查看this answer 以获得澄清。)

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

    >>> 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)]
    

    【讨论】:

      猜你喜欢
      • 2014-10-29
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      • 2018-09-05
      相关资源
      最近更新 更多