]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add pgcode / sqlstate for asyncpg error message
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 5 Apr 2021 18:41:31 +0000 (14:41 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 6 Apr 2021 00:13:01 +0000 (20:13 -0400)
Added accessors ``.sqlstate`` and synonym ``.pgcode`` to the ``.orig``
attribute of the SQLAlchemy exception class raised by the asyncpg DBAPI
adapter, that is, the intermediary exception object that wraps on top of
that raised by the asyncpg library itself, but below the level of the
SQLAlchemy dialect.

Fixes: #6199
Change-Id: Ie0f1ffaaff47c7a50dd1fbccdbe588cdc5322b70

doc/build/changelog/unreleased_14/6199.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/postgresql/asyncpg.py
test/dialect/postgresql/test_dialect.py

diff --git a/doc/build/changelog/unreleased_14/6199.rst b/doc/build/changelog/unreleased_14/6199.rst
new file mode 100644 (file)
index 0000000..0c81637
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+    :tags: usecase, asyncio, postgresql
+    :tickets: 6199
+
+    Added accessors ``.sqlstate`` and synonym ``.pgcode`` to the ``.orig``
+    attribute of the SQLAlchemy exception class raised by the asyncpg DBAPI
+    adapter, that is, the intermediary exception object that wraps on top of
+    that raised by the asyncpg library itself, but below the level of the
+    SQLAlchemy dialect.
index 8cd5bee41fcfc2e40ec9d08a71e33caf1c6cfe74..4a191cd286bb461789bb03bfc24ca48c4cf6fa0a 100644 (file)
@@ -646,6 +646,9 @@ class AsyncAdapt_asyncpg_connection:
                     translated_error = exception_mapping[super_](
                         "%s: %s" % (type(error), error)
                     )
+                    translated_error.pgcode = (
+                        translated_error.sqlstate
+                    ) = getattr(error, "sqlstate", None)
                     raise translated_error from error
             else:
                 raise error
index f407f2655a426c1abe06b1564f97a6acd4e381a2..1bd947f6a3e558621d3e20ebd973ccc01e91d880 100644 (file)
@@ -208,6 +208,30 @@ class DialectTest(fixtures.TestBase):
         eq_(cparams["host"], "hostA:portA,hostB,hostC")
 
 
+class PGCodeTest(fixtures.TestBase):
+    __only_on__ = "postgresql"
+
+    def test_error_code(self, metadata, connection):
+        t = Table("t", metadata, Column("id", Integer, primary_key=True))
+        t.create(connection)
+
+        errmsg = assert_raises(
+            exc.IntegrityError,
+            connection.execute,
+            t.insert(),
+            [{"id": 1}, {"id": 1}],
+        )
+
+        if testing.against("postgresql+pg8000"):
+            # TODO: is there another way we're supposed to see this?
+            eq_(errmsg.orig.args[0]["C"], "23505")
+        else:
+            eq_(errmsg.orig.pgcode, "23505")
+
+        if testing.against("postgresql+asyncpg"):
+            eq_(errmsg.orig.sqlstate, "23505")
+
+
 class ExecuteManyMode(object):
     __only_on__ = "postgresql+psycopg2"
     __backend__ = True