python - 事务和 sqlalchemy

标签 python insert transactions sqlalchemy

我正在尝试弄清楚如何在 Python 3 中使用 SQLAlchemy 将许多(大约 100k)记录插入到数据库中。一切都指向使用事务。但是,我对如何做到这一点感到有些困惑。

有些页面声明您从 connection.begin() 获得交易,其他地方说它是 session.begin() 而此页面 here说它是不存在的 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 之前完成这两个教程。他们真的很有帮助,可以解释很多概念。之后,我建议你阅读Using the Session然后继续解释 session 如何适应所有这些。

对于您的问题,有两种解决方案:一种使用 ORM,另一种使用 Core。前者更容易,后者更快。让我们先走容易的路。事务仅用于将所有语句包装到单个操作中。也就是说,如果某件事失败了,您可以中止所有这一切,而不会在两者之间留下任何东西。所以你很可能想要一个交易,但没有交易也可以。这是最快的方法:

with session.begin():
    session.add_all([tableRow(row) for row in listOfRows])

根据您的数据,SQLAlchemy 甚至可以优化您的 INSERT 语句,使其一次执行多个。这是正在发生的事情:

  • 使用 session.begin 开始事务
  • 数据被添加(使用add_all,但是一个有多个add的循环也可以)
  • session 已提交。如果此处出现问题,交易将中止,您可以修复错误。

所以这显然是一个好方法,但它不是最快的方法,因为 SQLAlchemy 必须经过所有 ORM 算法,这会产生一些开销。如果这是一次性数据库初始化,则可以避免使用 ORM。在这种情况下,不是创建一个 ORM 类 (tableRow),而是创建一个包含所有键的字典(如何取决于数据)。同样,您可以使用上下文管理器:

with engine.begin() as connection:
    connection.execute(tableRow.__table__.insert().
                       values([row_to_dict(row) for row in listOfRows]))

这很可能会稍微快一些,但也不太方便。它的工作方式与上面的 session 相同,只是它从核心而不是 ORM 构造语句。

关于python - 事务和 sqlalchemy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19904176/

相关文章:

python - 用 numpy 数组对任意数求幂

使用存储过程进行具有唯一约束的 SQL 插入

spring - 如何有效测试事务的酸度(Java/Spring/EJB 或其他)

python - Pandas 用 df.drop 删除行不起作用

python - 将多个文件中的 json 对象逐行合并到一个文件中

mysql - 使用单个查询将值插入多个表

php - 优惠券代码统计

java - 跨多个 EJB 的事务

java - 无状态 session EJB 3.0 中的事务回滚

python - 如果函数在 PYTHON 中没有按预期工作