]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Allow NUMERIC()/DECIMAL() IDENTITY columns
authorGord Thompson <gord@gordthompson.com>
Tue, 14 Jun 2022 16:09:04 +0000 (10:09 -0600)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 18 Jun 2022 18:00:12 +0000 (14:00 -0400)
Fixed issue where :class:`.Table` objects that made use of IDENTITY columns
with a :class:`.Numeric` datatype would produce errors when attempting to
reconcile the "autoincrement" column, preventing construction of the
:class:`.Column` from using the :paramref:`.Column.autoincrement` parameter
as well as emitting errors when attempting to invoke an :class:`.Insert`
construct.

Fixes: #8111
Change-Id: Iaacc4eebfbafb42fa18f9a1a4f43cb2b6b91d28a
(cherry picked from commit a134956c4e4564844c33302ddf27a70102fe00a8)

doc/build/changelog/unreleased_14/8111.rst [new file with mode: 0644]
lib/sqlalchemy/sql/schema.py
lib/sqlalchemy/sql/sqltypes.py
lib/sqlalchemy/sql/type_api.py
test/dialect/mssql/test_query.py

diff --git a/doc/build/changelog/unreleased_14/8111.rst b/doc/build/changelog/unreleased_14/8111.rst
new file mode 100644 (file)
index 0000000..ac43297
--- /dev/null
@@ -0,0 +1,11 @@
+.. change::
+    :tags: bug, schema, mssql
+    :tickets: 8111
+
+    Fixed issue where :class:`.Table` objects that made use of IDENTITY columns
+    with a :class:`.Numeric` datatype would produce errors when attempting to
+    reconcile the "autoincrement" column, preventing construction of the
+    :class:`.Column` from using the :paramref:`.Column.autoincrement` parameter
+    as well as emitting errors when attempting to invoke an :class:`.Insert`
+    construct.
+
index bc7e65d90c83da38dffcd2cec44119c46671415b..e89ac9ef5612301ada38299792a8394009dffff4 100644 (file)
@@ -4081,7 +4081,11 @@ class PrimaryKeyConstraint(ColumnCollectionConstraint):
     def _autoincrement_column(self):
         def _validate_autoinc(col, autoinc_true):
             if col.type._type_affinity is None or not issubclass(
-                col.type._type_affinity, type_api.INTEGERTYPE._type_affinity
+                col.type._type_affinity,
+                (
+                    type_api.INTEGERTYPE._type_affinity,
+                    type_api.NUMERICTYPE._type_affinity,
+                ),
             ):
                 if autoinc_true:
                     raise exc.ArgumentError(
index 306ac397df3c148893d90ddcb40fea237b2a50cd..fa50da65022b52f8ac4df171d60592e1205cd1ec 100644 (file)
@@ -3288,6 +3288,7 @@ NULLTYPE = NullType()
 BOOLEANTYPE = Boolean()
 STRINGTYPE = String()
 INTEGERTYPE = Integer()
+NUMERICTYPE = Numeric()
 MATCHTYPE = MatchType()
 TABLEVALUE = TableValueType()
 DATETIME_TIMEZONE = DateTime(timezone=True)
@@ -3342,6 +3343,7 @@ type_api.BOOLEANTYPE = BOOLEANTYPE
 type_api.STRINGTYPE = STRINGTYPE
 type_api.INTEGERTYPE = INTEGERTYPE
 type_api.NULLTYPE = NULLTYPE
+type_api.NUMERICTYPE = NUMERICTYPE
 type_api.MATCHTYPE = MATCHTYPE
 type_api.INDEXABLE = Indexable
 type_api.TABLEVALUE = TABLEVALUE
index 840668c378eaa251d7ebede623bea5843c2e7e28..7431c08a41d2f6b5ff76805dc6b7c1bd37a92df0 100644 (file)
@@ -22,6 +22,7 @@ from .. import util
 BOOLEANTYPE = None
 INTEGERTYPE = None
 NULLTYPE = None
+NUMERICTYPE = None
 STRINGTYPE = None
 MATCHTYPE = None
 INDEXABLE = None
index 4c02fc171c88ef7b11b58033d572cb25e597249d..3a34bf04cef21539331d4ac3b10f894c2ffd8f36 100644 (file)
@@ -1,4 +1,6 @@
 # -*- encoding: utf-8
+import decimal
+
 from sqlalchemy import and_
 from sqlalchemy import Column
 from sqlalchemy import DDL
@@ -9,6 +11,7 @@ from sqlalchemy import func
 from sqlalchemy import Identity
 from sqlalchemy import Integer
 from sqlalchemy import literal
+from sqlalchemy import Numeric
 from sqlalchemy import or_
 from sqlalchemy import PrimaryKeyConstraint
 from sqlalchemy import select
@@ -41,6 +44,13 @@ class IdentityInsertTest(fixtures.TablesTest, AssertsCompiledSQL):
             Column("description", String(50)),
             PrimaryKeyConstraint("id", name="PK_cattable"),
         )
+        Table(
+            "numeric_identity",
+            metadata,
+            Column("id", Numeric(18, 0), autoincrement=True),
+            Column("description", String(50)),
+            PrimaryKeyConstraint("id", name="PK_numeric_identity"),
+        )
 
     def test_compiled(self):
         cattable = self.tables.cattable
@@ -63,6 +73,13 @@ class IdentityInsertTest(fixtures.TablesTest, AssertsCompiledSQL):
         lastcat = conn.execute(cattable.select().order_by(desc(cattable.c.id)))
         eq_((10, "PHP"), lastcat.first())
 
+        numeric_identity = self.tables.numeric_identity
+        # for some reason, T-SQL does not like .values(), but this works
+        result = conn.execute(
+            numeric_identity.insert(), dict(description="T-SQL")
+        )
+        eq_(result.inserted_primary_key, (decimal.Decimal("1"),))
+
     def test_executemany(self, connection):
         conn = connection
         cattable = self.tables.cattable