mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-14 12:47:22 -04:00
Allow NUMERIC()/DECIMAL() IDENTITY columns
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
This commit is contained in:
committed by
Mike Bayer
parent
6d889b03dc
commit
a134956c4e
+11
@@ -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.
|
||||
|
||||
@@ -4540,7 +4540,11 @@ class PrimaryKeyConstraint(ColumnCollectionConstraint):
|
||||
def _autoincrement_column(self) -> Optional[Column[Any]]:
|
||||
def _validate_autoinc(col: Column[Any], autoinc_true: bool) -> bool:
|
||||
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(
|
||||
|
||||
@@ -459,6 +459,12 @@ class Numeric(HasExpressionLookup, TypeEngine[_N]):
|
||||
|
||||
__visit_name__ = "numeric"
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@util.ro_memoized_property
|
||||
def _type_affinity(self) -> Type[Numeric[_N]]:
|
||||
...
|
||||
|
||||
_default_decimal_return_scale = 10
|
||||
|
||||
def __init__(
|
||||
@@ -3553,6 +3559,7 @@ NULLTYPE = NullType()
|
||||
BOOLEANTYPE = Boolean()
|
||||
STRINGTYPE = String()
|
||||
INTEGERTYPE = Integer()
|
||||
NUMERICTYPE: Numeric[decimal.Decimal] = Numeric()
|
||||
MATCHTYPE = MatchType()
|
||||
TABLEVALUE = TableValueType()
|
||||
DATETIME_TIMEZONE = DateTime(timezone=True)
|
||||
@@ -3610,6 +3617,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 = Indexable
|
||||
type_api.TABLEVALUE = TABLEVALUE
|
||||
|
||||
@@ -50,6 +50,7 @@ if typing.TYPE_CHECKING:
|
||||
from .sqltypes import INTEGERTYPE as INTEGERTYPE # noqa: F401
|
||||
from .sqltypes import MATCHTYPE as MATCHTYPE # noqa: F401
|
||||
from .sqltypes import NULLTYPE as NULLTYPE
|
||||
from .sqltypes import NUMERICTYPE as NUMERICTYPE # noqa: F401
|
||||
from .sqltypes import STRINGTYPE as STRINGTYPE # noqa: F401
|
||||
from .sqltypes import TABLEVALUE as TABLEVALUE # noqa: F401
|
||||
from ..engine.interfaces import Dialect
|
||||
|
||||
@@ -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
|
||||
@@ -39,6 +42,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
|
||||
@@ -61,6 +71,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
|
||||
|
||||
Reference in New Issue
Block a user