【问题标题】:Is it possible to commit two related tables in a SQLAlchemy transaction?是否可以在 SQLAlchemy 事务中提交两个相关的表?
【发布时间】:2019-06-30 18:50:31
【问题描述】:

我正在通过 Flask-SQLAlchemy 使用更高级别的 SQLAlchemy ORM。我希望能够创建多个表,然后在单个事务中提交它们。但是,一个表与所有其他表相关,我不确定如何在它实际存在之前扩散它的 ID。 (请注意,它的主键是一个自增的值,在我们实际执行 SQL 之前不存在。)

例如,假设我们有TableATableBTableB 有一个名为 table_a_id 的列。 TableA ID 由数据库管理;它会自动递增,并且在我们创建一行 TableA 之前不存在。

我希望能够同时创建TableATableB,如果出现任何问题回滚事务。

在一个可以使用魔法的完美世界中,我的代码应该是这样的:

try:
    a = TableA()
    b = TableB(table_a_id=a.id)  # a.id is None, since nothing has happened yet.
    db.session.commit()
except Exception:
    db.session.rollback()

是否可以通过子交易在交易中填写a.id的值?

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    只需在创建 a 对象后使用 session.flush(),它会在当前事务中发出所有待处理的 SQL,并且填写自动生成的 ID。稍后您可以根据需要commit()rollback()

    【讨论】:

      【解决方案2】:

      我有两张表,一张是UnserInfo,另一张是clientInfo。在这种情况下,userInfoId 是 clientInfo 表中的外键。所以首先我保存 userInfo 然后用 userInfo id 保存 clientInfo

      这里我使用的是flask、marshmallow、flask-marshmallow、marshmallow-sqlalchemy、SQLAlchemy、flask-sqlalchemy。

      我在我的项目中就是这样做的

      try:
      
          userInfo = UserInfo(
             userId=dataUserInfo['mobile'],
             password=dataUserInfo['password'],
             userTypeName='client')
      
          db.session.add(userInfo)     
          db.session.commit() # save userInfo in database
          dbUserInfoResult = userInfoDto.dump(userInfo).data # get userInfo id from database
          print('dbUserInfoResult.data.id: ', dbUserInfoResult['id'])
      
          clientInfo = ClientInfo(name=dataClintInfo['name'],
                            mobileCountryCode=dataClintInfo['mobileCountryCode'],
                            mobile=dataClintInfo['mobile'],
                            email=dataClintInfo['email'] if 'email' in dataClintInfo else None,
                            userInfoId=dbUserInfoResult['id'])
      
          db.session.add(clientInfo)
          db.session.commit()
      except Exception:
          db.session.rollback()
      

      【讨论】:

      • 这不是交易的好选择。在事务中,如果您的程序在会话中间由于某种原因中止,则其中任何未提交的更改都将丢失。在您的解决方案中,如果服务器崩溃,则可能只会发生第一次提交。
      猜你喜欢
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多