[解決済み] トランザクションとsqlalchemy
質問
Python 3 の SQLAlchemy を使って、データベースに多数の(100k のオーダーで)レコードを挿入する方法を見つけようとしています。すべてはトランザクションを使うことを指します。しかし、それがどのように行われるのか、少し混乱しています。
いくつかのページでは、トランザクションを
connection.begin()
である場合と、他の場所では
session.begin()
そしてこのページ
ここで
と書いてあります。
session.create_transaction()
が存在しない。
以下は、私がやろうとしていることです。
def addToTable(listOfRows):
engine = create_engine('postgresql+pypostgresql:///%s' % db,echo = False)
Session = sessionmaker(bind = engine)
session = Session()
table = myTable(engine,session)
for row in listOfRows:
table.add(row)
table.flush() ### ideally there would be a counter and you flush after a couple of thousand records
class myTable:
def __init__(self,engine,session):
self.engine = engine
self.session = session
self.transaction =createTransaction()# Create transaction code here
def add(self,row):
newRow = tableRow(row) ## This just creates a representation of a row in the DB
self.transaction.add(newRow)
self.transaction.flush()
def flush(self):
self.transaction.commit()
解決方法は?
SQLAlchemyの旅を続ける前に、両方のチュートリアルをやっておくことを強くお勧めします。これらは本当に有用で、多くの概念を説明しています。その後、次の本を読むことをお勧めします セッションを使用する というのも、セッションがこのすべてにどのように関わっているのかを説明しているからです。
あなたの問題に対しては、2つの解決策があります。ひとつはORMを使ったもの、もうひとつはCoreを使ったものです。前者はより簡単で、後者はより速いです。まず、簡単なほうを考えてみましょう。トランザクションは、すべてのステートメントを1つの操作にラップするためにのみ使用されます。つまり、もし何かが失敗したら、そのすべてを中止することができ、どこかに何かが残っているわけではありません。ですから、ほとんどの場合、トランザクションが必要ですが、トランザクションがなくても動作するでしょう。ここでは、最も手っ取り早い方法を紹介します。
with session.begin():
session.add_all([tableRow(row) for row in listOfRows])
データによっては、SQLAlchemyがあなたの
INSERT
ステートメントを一度に複数回実行できるようにします。以下はその内容です。
-
を使用してトランザクションが開始されます。
session.begin
-
データが追加される (使用
add_all
というループがありますが、複数のadd
でもよい) - セッションがコミットされます。ここで何か問題が発生した場合、トランザクションは中断され、あなたはエラーを修正することができます。
なぜなら SQLAlchemy はすべての ORM アルゴリズムを通過しなければならないので、いくらかオーバーヘッドを生む可能性があるからです。もしこれが一度だけのデータベースの初期化なら、ORM を避けることができます。その場合、ORM クラスを作る代わりに (
tableRow
)、すべてのキーを持つ辞書を作成します(方法はデータによって異なります)。この場合も、コンテキスト・マネージャーを使用することができます。
with engine.begin() as connection:
connection.execute(tableRow.__table__.insert().
values([row_to_dict(row) for row in listOfRows]))
この方が若干速くなる可能性が高いですが、利便性も低くなります。これは上記のセッションと同じように動作しますが、ORMではなくCoreからステートメントを構築する点が異なります。
関連
-
[解決済み] 関数デコレータを作成し、それらを連鎖させるには?
-
[解決済み] staticmethodとclassmethodの違いについて
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] 割り当て後にリストが予期せず変更されました。その理由と防止策を教えてください。
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み] SQLAlchemy ORDER BY DESCENDING?
-
[解決済み] SQLAlchemy: flush() と commit() の違いは何ですか?
-
[解決済み】__str__と__repr__の違いは何ですか?
-
[解決済み】SQLAlchemyのfilterとfilter_byの違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python機械学習Githubが8.9Kstarsに達したモデルインタープリタLIME
-
PythonはWordの読み書きの変更操作を実装している
-
Python Pillow Image.save jpg画像圧縮問題
-
Python 入出力と高次代入の基礎知識
-
[解決済み】なぜ「LinAlgError: Grangercausalitytestsから「Singular matrix」と表示されるのはなぜですか?
-
[解決済み】 NameError: グローバル名 'xrange' は Python 3 で定義されていません。
-
[解決済み】TypeError: 系列を <class 'float'> に変換することができません。
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み] TypeError: 'DataFrame' オブジェクトは呼び出し可能ではない
-
[解決済み】Flaskのテンプレートが見つからない【重複あり