【问题标题】:Bulk insert into multiple tables using SQLAlchemy ORM使用 SQLAlchemy ORM 批量插入多个表
【发布时间】:2019-05-16 06:22:01
【问题描述】:

我正在尝试使用 Flask-SQLAlchemy 批量插入 2 个表。这两个表是:

  1. 作者表:PK author_id(自增)
  2. 书表:PK book_id (ai),FK author_author_id

在 JSON 的正文中,我有一个字典列表。每个字典条目都有一些与作者相关的信息和一些与书籍相关的信息。像这样,可以一次性发送更多的字典:

[
    {
        "author_first_name": "John",
        "author_last_name": "Doe",
        "author_yob": "1988",
        "book_name": "Mournings of a nun",
        "book_genre": "Drama"
    },
    {
        "author_first_name": "Jane",
        "author_last_name": "Doe",
        "author_yob": "1987",
        "book_name": "Need for speed",
        "book_genre": "Action"
    }
]

目前,我正在遍历每个字典,将数据插入 author 表,然后插入 book 表。当我插入作者表并提交时,我得到一个主键,即 author_id。那是我的 book 表的外键。

我对该列表中的每个条目重复此步骤。有没有办法进行批量插入,以便如果任何插入失败,所有内容都会回滚并且我的数据库中没有不一致的数据?因此,如果上面的 JSON 中有 15 个字典,如果第 12 个有一些无效数据或数据库出现故障,我希望 JSON 中发送的任何数据都不应该发布到 AWS RDS。下面,“结果”指的是我上面提到的 JSON。

    @classmethod
    def post_to_database(cls, results):
        for result in results:
            BookModel.post_entry_to_database(result)


    @classmethod
    def post_entry_to_database(cls, result):
        BookModel.insert_author_entry(result)
        author_id = BookModel.get_author_id(result)
        BookModel.insert_book_entry(author_id, result)


    @classmethod
    def insert_book_entry(cls, author_id, result):
        book_data = BookModel(result["testname"], result["result"], author_id)
        db.session.add(book_data)
        db.session.commit()

同样,我也有 insert_author_entry。

谢谢, 阿迪亚

【问题讨论】:

    标签: python mysql sqlalchemy flask-sqlalchemy bulkinsert


    【解决方案1】:

    您可以考虑使用flush() 刷新对数据库的更改,这将更新您的主键字段。

    来自 SqlAlchemy 文档:flush

    数据库操作将在当前事务上下文中发出并且不会影响事务的状态,除非发生错误,在这种情况下整个事务被回滚。您可以在事务中尽可能频繁地刷新(),以将更改从 Python 移动到数据库的事务缓冲区。

    当调用 flush 时,数据库将您的 CRUD 操作保持为在事务中挂起,并且在数据库收到当前事务的 COMMIT 之前不会永久持久化。这将在您随后调用 commit() 时发生。

    【讨论】:

      猜你喜欢
      • 2011-04-09
      • 1970-01-01
      • 2021-06-25
      • 2019-10-24
      • 2018-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      相关资源
      最近更新 更多