Skip to content

Commit

Permalink
Integer primary key on _sqlite_migrations, refs #6
Browse files Browse the repository at this point in the history
  • Loading branch information
simonw committed Mar 13, 2024
1 parent 0587a1a commit 5ed0d50
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 19 deletions.
13 changes: 9 additions & 4 deletions sqlite_migrate/__init__.py
Expand Up @@ -94,15 +94,20 @@ def ensure_migrations_table(self, db: "Database"):
if not table.exists():
table.create(
{
"id": int,
"migration_set": str,
"name": str,
"applied_at": str,
},
pk=("migration_set", "name"),
pk="id",
)
elif table.pks != ["migration_set", "name"]:
# This has the old primary key scheme, upgrade it
table.transform(pk=("migration_set", "name"))
table.create_index(["migration_set", "name"], unique=True)
elif table.pks != ["id"]:
# This has an older primary key scheme, upgrade it
table.transform(pk="id")
unique_indexes = {tuple(index.columns) for index in table.indexes}
if ("migration_set", "name") not in unique_indexes:
table.create_index(["migration_set", "name"], unique=True)

def __repr__(self):
return "<Migrations '{}': [{}]>".format(
Expand Down
39 changes: 28 additions & 11 deletions tests/test_sqlite_migrate.py
Expand Up @@ -81,18 +81,35 @@ def test_order_does_not_matter(migrations, migrations_not_ordered_alphabetically
assert db1.schema == db2.schema


def test_upgrades_sqlite_migrations_from_one_to_two_primary_keys(migrations):
@pytest.mark.parametrize(
"create_table,pk",
(
# Original with pk name
(
{
"migration_set": str,
"name": str,
"applied_at": str,
},
"name",
),
# Second version pk migraiton_set, name
(
{
"migration_set": str,
"name": str,
"applied_at": str,
},
("migration_set", "name"),
),
),
)
def test_upgrades_sqlite_migrations(migrations, create_table, pk):
db = sqlite_utils.Database(memory=True)
db["_sqlite_migrations"].create(
{
"migration_set": str,
"name": str,
"applied_at": str,
},
pk="name",
)
table = db["_sqlite_migrations"].create(create_table, pk=pk)
print(table.schema)
# Applying migrations should fix that
assert db.table_names() == ["_sqlite_migrations"]
assert db["_sqlite_migrations"].pks == ["name"]
assert db["_sqlite_migrations"].pks == [pk] if isinstance(pk, str) else pk
migrations.apply(db)
assert db["_sqlite_migrations"].pks == ["migration_set", "name"]
assert db["_sqlite_migrations"].pks == ["id"]
10 changes: 6 additions & 4 deletions tests/test_sqlite_utils_migrate_command.py
Expand Up @@ -103,11 +103,13 @@ def foo(db):
Schema before:
CREATE TABLE [_sqlite_migrations] (
[id] INTEGER PRIMARY KEY,
[migration_set] TEXT,
[name] TEXT,
[applied_at] TEXT,
PRIMARY KEY ([migration_set], [name])
[applied_at] TEXT
);
CREATE UNIQUE INDEX [idx__sqlite_migrations_migration_set_name]
ON [_sqlite_migrations] ([migration_set], [name]);
CREATE TABLE [dogs] (
[id] INTEGER,
[name] TEXT
Expand Down Expand Up @@ -137,9 +139,9 @@ def bar(db):
expected_diff = """
Schema diff:
[applied_at] TEXT,
PRIMARY KEY ([migration_set], [name])
);
CREATE UNIQUE INDEX [idx__sqlite_migrations_migration_set_name]
ON [_sqlite_migrations] ([migration_set], [name]);
-CREATE TABLE [dogs] (
+CREATE TABLE "dogs" (
[id] INTEGER,
Expand Down

0 comments on commit 5ed0d50

Please sign in to comment.