Fix transform() dropping AUTOINCREMENT from INTEGER PRIMARY KEY columns

Calling .transform() on a table with INTEGER PRIMARY KEY AUTOINCREMENT
recreated the table without the AUTOINCREMENT keyword, silently changing
the table's behaviour so that deleted row IDs could be reused.

The fix adds an autoincrement parameter to create_table_sql() and detects
AUTOINCREMENT in the existing schema before calling it from transform_sql().
This commit is contained in:
ikatyal21 2026-07-12 14:18:21 +00:00
commit 05b5f0fe26
No known key found for this signature in database
2 changed files with 25 additions and 0 deletions

View file

@ -1400,6 +1400,7 @@ class Database:
extracts: Optional[Union[Dict[str, str], List[str]]] = None,
if_not_exists: bool = False,
strict: bool = False,
autoincrement: bool = False,
) -> str:
"""
Returns the SQL ``CREATE TABLE`` statement for creating the specified table.
@ -1496,6 +1497,8 @@ class Database:
column_extras = []
if column_name == single_pk:
column_extras.append("PRIMARY KEY")
if autoincrement:
column_extras.append("AUTOINCREMENT")
if column_name in not_null:
column_extras.append("NOT NULL")
if column_name in defaults and defaults[column_name] is not None:
@ -2807,6 +2810,8 @@ class Table(Queryable):
if column_order is not None:
column_order = [rename.get(col) or col for col in column_order]
has_autoincrement = "autoincrement" in self.schema.lower()
sqls = []
sqls.append(
self.db.create_table_sql(
@ -2818,6 +2823,7 @@ class Table(Queryable):
foreign_keys=create_table_foreign_keys,
column_order=column_order,
strict=self.strict if strict is None else strict,
autoincrement=has_autoincrement,
).strip()
)

View file

@ -758,6 +758,25 @@ def test_transform_with_indexes_errors(fresh_db, transform_params):
)
def test_transform_preserves_autoincrement(fresh_db):
fresh_db.execute(
"CREATE TABLE t (id INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)"
)
fresh_db["t"].insert({"val": "one"})
fresh_db["t"].insert({"val": "two"})
fresh_db["t"].transform(rename={"val": "value"})
assert "AUTOINCREMENT" in fresh_db["t"].schema
# Confirm the column is still the primary key
assert fresh_db["t"].pks == ["id"]
def test_transform_without_autoincrement_not_affected(fresh_db):
fresh_db.execute("CREATE TABLE t (id INTEGER PRIMARY KEY, val TEXT)")
fresh_db["t"].insert({"val": "one"})
fresh_db["t"].transform(rename={"val": "value"})
assert "AUTOINCREMENT" not in fresh_db["t"].schema
def test_transform_with_unique_constraint_implicit_index(fresh_db):
dogs = fresh_db["dogs"]
# Create a table with a UNIQUE constraint on 'name', which creates an implicit index