4

私は、7つの要素(列)を持つ最大500のタプル(行)のリストをデータベースに挿入する方法を研究してきました。私はstackoverflowや他のフォーラムに関するさまざまな投稿を読みました。私は以下を見つけました、そしてそれは'executemany()'メソッドを使うことを提案します、しかしそれは私にはその方法がそれほど明確ではありません。オブジェクトをタプルから辞書に変換する必要がありますか?問題は、name:valueタイプのデータ構造がないことです。

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年には、SQLAlchemy1.4とPython3.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))

dateSQLite DB-APIライブラリはここdatetime.dateに記載されているようにPythonを必要としているため、簡単にするために、フィールドを文字列に変更したことに気付くかもしれません。(この小さな手先の早業に戸惑う人は、明確にするためにこの答えを見る必要があります。)

とにかく、2次元データ構造を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 に答える