使用SQLAlchemy ORM

时间:2018-12-15 01:44:59

标签: python mysql sqlalchemy flask-sqlalchemy bulkinsert

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

  1. author表: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。那是我的书桌的外键。

我对该列表中的每个条目重复此步骤。有没有一种方法可以进行批量插入,因此,如果任何插入失败,则所有内容都会回滚,并且我的数据库中没有不一致的数据?因此,如果上面的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。

谢谢, 阿迪亚(Aditya)

1 个答案:

答案 0 :(得分:1)

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

来自SqlAlchemy文档:flush

  

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

在调用flush时,数据库会将您的CRUD操作保持为事务中的未决状态,并且直到数据库收到该当前事务的COMMIT时才永久保留。当您随后致电commit()时,就会发生这种情况。