Skip to content

autogenerate and sync migrations with models #8239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 18, 2024
Merged

Conversation

wardi
Copy link
Contributor

@wardi wardi commented May 23, 2024

Fixes #8238

Proposed fixes:

  • add ckan generate migration --autogenerate alembic feature
  • add migrations to remove unnecessary tables, indexes
  • add indexes to models

Features:

  • includes tests covering changes
  • includes updated documentation
  • includes user-visible changes
  • includes API changes
  • includes bugfix for possible backport

@wardi wardi marked this pull request as ready for review June 6, 2024 20:59
@smotornyuk
Copy link
Member

@wardi, everything works like a charm with a core and can be merged, but autogeneration for plugins doesn't work right now.

The only problem is missing metadata in the alembic template. With metadata, plugins can use autogeneration as well.

But I think you should use an addition to plugin migrations. Just like you did for core migrations with include_name we can use a filter that skips any table if its name isn't prefixed by plugin name.

There is always a chance that somebody will use different table-naming convention. But we'll document the fact that metadata must be updated in existing migration scripts and can also mention this filter and its implications.

And for plugins we can use include_object instead of include_name. I noticed that it works better with plugins(for core migration there is no difference).

Here's the patch with my suggestion:

diff --git a/ckanext/activity/migration/activity/env.py b/ckanext/activity/migration/activity/env.py
index 4709aa4b1..ff9af0414 100644
--- a/ckanext/activity/migration/activity/env.py
+++ b/ckanext/activity/migration/activity/env.py
@@ -4,6 +4,7 @@ from __future__ import with_statement
 from alembic import context
 from sqlalchemy import engine_from_config, pool
 from logging.config import fileConfig
+from ckan.model.meta import metadata
 
 import os
 
@@ -20,7 +21,7 @@ fileConfig(config.config_file_name)
 # for 'autogenerate' support
 # from myapp import mymodel
 # target_metadata = mymodel.Base.metadata
-target_metadata = None
+target_metadata = metadata
 
 # other values from the config, defined by the needs of env.py,
 # can be acquired:
@@ -30,6 +31,12 @@ target_metadata = None
 name = os.path.basename(os.path.dirname(__file__))
 
 
+def include_object(object, object_name, type_, reflected, compare_to):
+    if type_ == "table":
+        return object_name.startswith(name)
+    return True
+
+
 def run_migrations_offline():
     """Run migrations in 'offline' mode.
 
@@ -46,7 +53,8 @@ def run_migrations_offline():
     url = config.get_main_option(u"sqlalchemy.url")
     context.configure(
         url=url, target_metadata=target_metadata, literal_binds=True,
-        version_table=u'{}_alembic_version'.format(name)
+        version_table=u'{}_alembic_version'.format(name),
+        include_object=include_object,
     )
 
     with context.begin_transaction():
@@ -69,7 +77,8 @@ def run_migrations_online():
         context.configure(
             connection=connection,
             target_metadata=target_metadata,
-            version_table=u'{}_alembic_version'.format(name)
+            version_table=u'{}_alembic_version'.format(name),
+            include_object=include_object,
         )
 
         with context.begin_transaction():
diff --git a/contrib/alembic/generic/env.py b/contrib/alembic/generic/env.py
index 009368218..bb2fcd412 100644
--- a/contrib/alembic/generic/env.py
+++ b/contrib/alembic/generic/env.py
@@ -4,6 +4,7 @@ from __future__ import with_statement
 from alembic import context
 from sqlalchemy import engine_from_config, pool
 from logging.config import fileConfig
+from ckan.model.meta import metadata
 
 import os
 
@@ -19,7 +20,7 @@ fileConfig(config.config_file_name)
 # for 'autogenerate' support
 # from myapp import mymodel
 # target_metadata = mymodel.Base.metadata
-target_metadata = None
+target_metadata = metadata
 
 # other values from the config, defined by the needs of env.py,
 # can be acquired:
@@ -29,6 +30,12 @@ target_metadata = None
 name = os.path.basename(os.path.dirname(__file__))
 
 
+def include_object(object, object_name, type_, reflected, compare_to):
+    if type_ == "table":
+        return object_name.startswith(name)
+    return True
+
+
 def run_migrations_offline():
     """Run migrations in 'offline' mode.
 
@@ -45,7 +52,8 @@ def run_migrations_offline():
     url = config.get_main_option(u"sqlalchemy.url")
     context.configure(
         url=url, target_metadata=target_metadata, literal_binds=True,
-        version_table=u'{}_alembic_version'.format(name)
+        version_table=u'{}_alembic_version'.format(name),
+        include_object=include_object,
     )
 
     with context.begin_transaction():
@@ -68,7 +76,8 @@ def run_migrations_online():
         context.configure(
             connection=connection,
             target_metadata=target_metadata,
-            version_table=u'{}_alembic_version'.format(name)
+            version_table=u'{}_alembic_version'.format(name),
+            include_object=include_object,
         )
 
         with context.begin_transaction():

@smotornyuk smotornyuk merged commit 28f7cf1 into master Jun 18, 2024
@smotornyuk smotornyuk deleted the 8238-sync-migrations branch June 18, 2024 13:01
@wardi
Copy link
Contributor Author

wardi commented Jun 18, 2024

@amercader WDYT about including this change in 2.11?

@amercader
Copy link
Member

sure, this is definitely useful

@amercader
Copy link
Member

/backport please

@ckanbot
Copy link

ckanbot commented Jun 18, 2024

Successfully created backport PR for dev-v2.11:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

alembic revision --autogenerate
4 participants