From 3d00c101be9feb73b87b8ad07ddc5bc14cd94cdb Mon Sep 17 00:00:00 2001 From: Federico Caselli Date: Fri, 10 Feb 2023 21:37:20 +0100 Subject: [PATCH] Add ``Table.autoincrement_column`` Added public property :attr:`_sql.Table.autoincrement_column` that returns the column identified as autoincrementing in the column. Fixes: #9277 Change-Id: If60d6f92e0df94f57d00ff6d89d285c61b02f5a4 --- doc/build/changelog/unreleased_20/9277.rst | 6 +++++ lib/sqlalchemy/sql/schema.py | 26 ++++++++++++++++++++-- test/sql/test_defaults.py | 2 ++ 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 doc/build/changelog/unreleased_20/9277.rst diff --git a/doc/build/changelog/unreleased_20/9277.rst b/doc/build/changelog/unreleased_20/9277.rst new file mode 100644 index 0000000000..b73649a88f --- /dev/null +++ b/doc/build/changelog/unreleased_20/9277.rst @@ -0,0 +1,6 @@ +.. change:: + :tags: sql + :tickets: 9277 + + Added public property :attr:`_sql.Table.autoincrement_column` that + returns the column identified as autoincrementing in the column. diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index 976432721c..2a713fea63 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -1001,9 +1001,31 @@ class Table( pass @util.ro_non_memoized_property - def _autoincrement_column(self) -> Optional[Column[Any]]: + def _autoincrement_column(self) -> Optional[Column[int]]: return self.primary_key._autoincrement_column + @property + def autoincrement_column(self) -> Optional[Column[int]]: + """Returns the :class:`.Column` object which currently represents + the "auto increment" column, if any, else returns None. + + This is based on the rules for :class:`.Column` as defined by the + :paramref:`.Column.autoincrement` parameter, which generally means the + column within a single integer column primary key constraint that is + not constrained by a foreign key. If the table does not have such + a primary key constraint, then there's no "autoincrement" column. + A :class:`.Table` may have only one column defined as the + "autoincrement" column. + + .. versionadded:: 2.0.4 + + .. seealso:: + + :paramref:`.Column.autoincrement` + + """ + return self._autoincrement_column + @property def key(self) -> str: """Return the 'key' for this :class:`_schema.Table`. @@ -4756,7 +4778,7 @@ class PrimaryKeyConstraint(ColumnCollectionConstraint): return list(self._columns) @util.ro_memoized_property - def _autoincrement_column(self) -> Optional[Column[Any]]: + def _autoincrement_column(self) -> Optional[Column[int]]: def _validate_autoinc(col: Column[Any], autoinc_true: bool) -> bool: if col.type._type_affinity is None or not issubclass( col.type._type_affinity, diff --git a/test/sql/test_defaults.py b/test/sql/test_defaults.py index cc7daf4017..e52499ab48 100644 --- a/test/sql/test_defaults.py +++ b/test/sql/test_defaults.py @@ -1111,6 +1111,7 @@ class AutoIncrementTest(fixtures.TestBase): id_ = r.inserted_primary_key[0] eq_(id_, 1) eq_(connection.scalar(sa.select(single.c.id)), 1) + assert single.autoincrement_column is single.c.id def test_autoinc_detection_no_affinity(self): class MyType(TypeDecorator): @@ -1120,6 +1121,7 @@ class AutoIncrementTest(fixtures.TestBase): assert MyType()._type_affinity is None t = Table("x", MetaData(), Column("id", MyType(), primary_key=True)) assert t._autoincrement_column is None + assert t.autoincrement_column is None def test_autoincrement_ignore_fk(self): m = MetaData() -- 2.47.2