Transactions with Python sqlite3

后端 未结 7 1658
梦如初夏
梦如初夏 2020-12-07 17:33

I\'m trying to port some code to Python that uses sqlite databases, and I\'m trying to get transactions to work, and I\'m getting really confused. I\'m really confused by th

7条回答
  •  再見小時候
    2020-12-07 18:31

    Here's what I think is happening based on my reading of Python's sqlite3 bindings as well as official Sqlite3 docs. The short answer is that if you want a proper transaction, you should stick to this idiom:

    with connection:
        db.execute("BEGIN")
        # do other things, but do NOT use 'executescript'
    

    Contrary to my intuition, with connection does not call BEGIN upon entering the scope. In fact it doesn't do anything at all in __enter__. It only has an effect when you __exit__ the scope, choosing either COMMIT or ROLLBACK depending on whether the scope is exiting normally or with an exception.

    Therefore, the right thing to do is to always explicitly mark the beginning of your transactions using BEGIN. This renders isolation_level irrelevant within transactions, because thankfully it only has an effect while autocommit mode is enabled, and autocommit mode is always suppressed within transaction blocks.

    Another quirk is executescript, which always issues a COMMIT before running your script. This can easily mess up the transactions, so your choice is to either

    • use exactly one executescript within a transaction and nothing else, or
    • avoid executescript entirely; you can call execute as many times as you want, subject to the one-statement-per-execute limitation.

提交回复
热议问题