gpt4 book ai didi

python - 如何防止 sqlalchemy 在 select 上创建事务?

转载 作者:太空宇宙 更新时间:2023-11-03 16:11:22 25 4
gpt4 key购买 nike

我的问题:

我有一个包含多行数据的文件。我想尝试将每一行插入我的数据库,但如果任何行有问题,我需要回滚整个工具包和kaboodle。但我想跟踪实际的错误,所以我可以这样说,而不是仅仅死在第一个有错误的记录上:

This file has 42 errors in it.

Line 1 is missing a whirlygig.
Line 2 is a duplicate.
Line 5 is right out.

我尝试执行此操作的方法是使用事务,但我遇到一个问题,SQLAlchemy 在 select 上创建隐式事务,显然我并不真正理解 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 上创建事务吗?或者我在这里遗漏了什么?有更好的方法来实现我想要的吗?

最佳答案

看起来 begin_nestedwith block 是正确的选择。

begin_nested(), in the same manner as the less often used begin() method... - sqlalchemy docs

这让我相信 begin_nested 是首选选项。

def insert_some_stuff(session, data):
try:
with session.begin_nested():
value = session.query(Whatever.value).limit(1).scalar()
session.add(Whatever(quux=data, value='hi'))
errors = 0
except sa.exc.IntegrityError:
errors = 1

return errors

通过使用 with block ,它在提交/回滚时执行正确的操作™,并且不会回滚太远。

关于python - 如何防止 sqlalchemy 在 select 上创建事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39277841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com