| 1 | import django
|
|---|
| 2 | from django.db import DatabaseError, connection, transaction
|
|---|
| 3 | from django.conf import settings
|
|---|
| 4 |
|
|---|
| 5 | settings.configure(
|
|---|
| 6 | DATABASES={"default": {
|
|---|
| 7 | "ENGINE": "django.db.backends.sqlite3",
|
|---|
| 8 | "NAME": "/tmp/dangle.sqlite3",
|
|---|
| 9 | }},
|
|---|
| 10 | INSTALLED_APPS=[],
|
|---|
| 11 | )
|
|---|
| 12 | django.setup()
|
|---|
| 13 |
|
|---|
| 14 | try:
|
|---|
| 15 | with connection.schema_editor(atomic=True) as editor:
|
|---|
| 16 | # The schema editor's __exit__ runs this and raises before it gets to
|
|---|
| 17 | # self.atomic.__exit__, so the transaction it opened is never closed.
|
|---|
| 18 | editor.deferred_sql.append("sql nonsense that will raise an error")
|
|---|
| 19 | except DatabaseError as e:
|
|---|
| 20 | print("deferred sql raised:", e)
|
|---|
| 21 |
|
|---|
| 22 | # The with block is over. This should be False.
|
|---|
| 23 | print("in_atomic_block:", connection.in_atomic_block)
|
|---|
| 24 |
|
|---|
| 25 | # We shouldn't be in an atomic block, so durable=True is fine.
|
|---|
| 26 | try:
|
|---|
| 27 | with transaction.atomic(durable=True):
|
|---|
| 28 | pass
|
|---|
| 29 | except RuntimeError as e:
|
|---|
| 30 | print("atomic(durable=True):", e)
|
|---|
| 31 |
|
|---|
| 32 | # A connection should work after .close().
|
|---|
| 33 | connection.close()
|
|---|
| 34 | try:
|
|---|
| 35 | connection.cursor().execute("SELECT 1")
|
|---|
| 36 | except Exception as e:
|
|---|
| 37 | print("query after close():", e)
|
|---|