Begin a nested transaction (i.e. SAVEPOINT) and return a transaction handle that controls the scope of the SAVEPOINT. E.g.:: with engine.begin() as connection: with connection.begin_nested(): connection.execute(table.insert(), {"usern
(self)
| 881 | ) |
| 882 | |
| 883 | def begin_nested(self) -> NestedTransaction: |
| 884 | """Begin a nested transaction (i.e. SAVEPOINT) and return a transaction |
| 885 | handle that controls the scope of the SAVEPOINT. |
| 886 | |
| 887 | E.g.:: |
| 888 | |
| 889 | with engine.begin() as connection: |
| 890 | with connection.begin_nested(): |
| 891 | connection.execute(table.insert(), {"username": "sandy"}) |
| 892 | |
| 893 | The returned object is an instance of |
| 894 | :class:`_engine.NestedTransaction`, which includes transactional |
| 895 | methods :meth:`_engine.NestedTransaction.commit` and |
| 896 | :meth:`_engine.NestedTransaction.rollback`; for a nested transaction, |
| 897 | these methods correspond to the operations "RELEASE SAVEPOINT <name>" |
| 898 | and "ROLLBACK TO SAVEPOINT <name>". The name of the savepoint is local |
| 899 | to the :class:`_engine.NestedTransaction` object and is generated |
| 900 | automatically. Like any other :class:`_engine.Transaction`, the |
| 901 | :class:`_engine.NestedTransaction` may be used as a context manager as |
| 902 | illustrated above which will "release" or "rollback" corresponding to |
| 903 | if the operation within the block were successful or raised an |
| 904 | exception. |
| 905 | |
| 906 | Nested transactions require SAVEPOINT support in the underlying |
| 907 | database, else the behavior is undefined. SAVEPOINT is commonly used to |
| 908 | run operations within a transaction that may fail, while continuing the |
| 909 | outer transaction. E.g.:: |
| 910 | |
| 911 | from sqlalchemy import exc |
| 912 | |
| 913 | with engine.begin() as connection: |
| 914 | trans = connection.begin_nested() |
| 915 | try: |
| 916 | connection.execute(table.insert(), {"username": "sandy"}) |
| 917 | trans.commit() |
| 918 | except exc.IntegrityError: # catch for duplicate username |
| 919 | trans.rollback() # rollback to savepoint |
| 920 | |
| 921 | # outer transaction continues |
| 922 | connection.execute(...) |
| 923 | |
| 924 | If :meth:`_engine.Connection.begin_nested` is called without first |
| 925 | calling :meth:`_engine.Connection.begin` or |
| 926 | :meth:`_engine.Engine.begin`, the :class:`_engine.Connection` object |
| 927 | will "autobegin" the outer transaction first. This outer transaction |
| 928 | may be committed using "commit-as-you-go" style, e.g.:: |
| 929 | |
| 930 | with engine.connect() as connection: # begin() wasn't called |
| 931 | |
| 932 | with connection.begin_nested(): # will auto-"begin()" first |
| 933 | connection.execute(...) |
| 934 | # savepoint is released |
| 935 | |
| 936 | connection.execute(...) |
| 937 | |
| 938 | # explicitly commit outer transaction |
| 939 | connection.commit() |
| 940 |
nothing calls this directly
no test coverage detected