私の問題:sqlalchemyがselectでトランザクションを作成しないようにするにはどうすればよいですか?
私はそこにいくつかのデータ行を持つファイルを持っています。私はを試してください私のデータベースにすべての行を挿入するが、のいずれかの行のに問題がある場合、私はキットとkaboodle全体をロールバックする必要があります。しかし、私は実際のエラーを追跡したいので、エラーがある最初のレコードで死んでいるのではなく、次のように言うことができます。
このファイルには42個のエラーがあります。
Line 1 is missing a whirlygig. Line 2 is a duplicate. Line 5 is right out.
私はこれをやろうとしている方法は、トランザクションを使用することですが、私はSQLAlchemyのセレクトに暗黙のトランザクションを作成し、問題を抱えている、と明らかに私は本当に何もないので、SQLAlchemyのは、トランザクションを使用する方法を理解していません私は自分が望むやり方で働くようです。ここに私の問題を示し、いくつかのコードは次のとおりです。
import sqlalchemy as sa
import logging
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
l = logging.getLogger('sqlalchemy.engine')
l.setLevel(logging.INFO)
l.addHandler(logging.StreamHandler())
engine = sa.create_engine('YOUR PG CONNECTION HERE')
Session = sessionmaker(bind=engine)
session = Session()
temp_metadata = sa.MetaData(schema='pg_temp')
TempBase = declarative_base(metadata=temp_metadata)
class Whatever(TempBase):
__tablename__ = 'whatevs'
id = sa.Column('id', sa.Integer, primary_key=True, autoincrement=True)
fnord = sa.Column('fnord', sa.String, server_default=sa.schema.FetchedValue())
quux = sa.Column('quux', sa.String)
value = sa.Column('value', sa.String)
def insert_some_stuff(session, data):
value = session.query(Whatever.value).limit(1).scalar()
session.add(Whatever(quux=data, value='hi'))
try:
session.commit()
errors = 0
except sa.exc.IntegrityError:
session.rollback()
errors = 1
return errors
with session.begin_nested():
session.execute('''
CREATE TABLE pg_temp.whatevs (
id serial
, fnord text not null default 'fnord'
, quux text not null
, value text not null
, CONSTRAINT totally_unique UNIQUE (quux)
);
INSERT INTO pg_temp.whatevs (value, quux) VALUES ('something cool', 'fnord');
''')
w = Whatever(value='something cool', quux='herp')
session.add(w)
errors = 0
for q in ('foo', 'biz', 'bang', 'herp'):
with session.begin_nested():
errors += insert_some_stuff(session, q)
for row in session.query(Whatever).all():
print(row.id, row.fnord, row.value)
私はsession.begin()
または.begin(subtransactions=True)
を行うさまざまな組み合わせを試してみたが、彼らは仕事、またはちょうど私がトランザクションをコミットしていますので、本当に奇妙ないないようですすべてのいずれか私は(明示的に)始めたことはありません。
sqlalchemyがselectでトランザクションを作成しないようにすることはできますか?または私はここに何かを逃していますか?私が欲しいものを達成する良い方法はありますか?
SQLAlchemyがこれらのトランザクションを作成するのはなぜ問題でしょうか? – user2357112
最後のトランザクションをクローズするときにトランザクションがクローズするか、*明白な* 'begin'を持たないこの' commit'/'rollback'コールがあるので –
これは役に立ちますか? http://docs.sqlalchemy.org/en/latest/orm/session_transaction.html#joining-a-session-into-an-external-transaction-such-as-for-test-suites – ACV