mirror of
				https://github.com/carrotquest/django-clickhouse.git
				synced 2025-10-31 16:07:56 +03:00 
			
		
		
		
	Created separate from infi MigrationHistory in order to:
1) inherit it from this library models 2) Use some extra functionality
This commit is contained in:
		
							parent
							
								
									0268cc230a
								
							
						
					
					
						commit
						d830b74bcb
					
				|  | @ -20,6 +20,7 @@ DEFAULTS = { | ||||||
|     'DATABASE_ROUTER': 'django_clickhouse.routers.DefaultRouter', |     'DATABASE_ROUTER': 'django_clickhouse.routers.DefaultRouter', | ||||||
|     'STATSD_PREFIX': 'clickhouse', |     'STATSD_PREFIX': 'clickhouse', | ||||||
|     'MIGRATIONS_PACKAGE': 'clickhouse_migrations', |     'MIGRATIONS_PACKAGE': 'clickhouse_migrations', | ||||||
|  |     'MIGRATION_HISTORY_MODEL': 'django_clickhouse.migrations.MigrationHistory', | ||||||
|     'MIGRATE_WITH_DEFAULT_DB': True, |     'MIGRATE_WITH_DEFAULT_DB': True, | ||||||
|     'CELERY_QUEUE': 'celery', |     'CELERY_QUEUE': 'celery', | ||||||
|     'DEFAULT_DB_ALIAS': 'default' |     'DEFAULT_DB_ALIAS': 'default' | ||||||
|  |  | ||||||
|  | @ -24,19 +24,7 @@ class Database(InfiDatabase): | ||||||
|                                   ' Use django_clickhouse.migrations module instead.') |                                   ' Use django_clickhouse.migrations module instead.') | ||||||
| 
 | 
 | ||||||
|     def _get_applied_migrations(self, migrations_package_name): |     def _get_applied_migrations(self, migrations_package_name): | ||||||
|         # I don't want to create any tables here, so I changed method to work in without table |         raise NotImplementedError("This method is not supported by django_clickhouse.") | ||||||
|         if not self.db_exists: |  | ||||||
|             return [] |  | ||||||
| 
 |  | ||||||
|         query = "SELECT module_name from $table WHERE package_name = '%s'" % migrations_package_name |  | ||||||
|         query = self._substitute(query, MigrationHistory) |  | ||||||
|         try: |  | ||||||
|             return set(obj.module_name for obj in self.select(query)) |  | ||||||
|         except ServerError as ex: |  | ||||||
|             # Database doesn't exist or table doesn't exist |  | ||||||
|             if ex.code in {81, 60}: |  | ||||||
|                 return set() |  | ||||||
|             raise ex |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ConnectionProxy: | class ConnectionProxy: | ||||||
|  |  | ||||||
|  | @ -2,11 +2,14 @@ | ||||||
| Migrating database | Migrating database | ||||||
| """ | """ | ||||||
| import datetime | import datetime | ||||||
| from typing import Optional | from typing import Optional, Set | ||||||
| 
 | 
 | ||||||
| from django.db import DEFAULT_DB_ALIAS as DJANGO_DEFAULT_DB_ALIAS | from django.db import DEFAULT_DB_ALIAS as DJANGO_DEFAULT_DB_ALIAS | ||||||
| from django.db.models.signals import post_migrate | from django.db.models.signals import post_migrate | ||||||
| from django.dispatch import receiver | from django.dispatch import receiver | ||||||
|  | from infi.clickhouse_orm.database import ServerError | ||||||
|  | 
 | ||||||
|  | from django_clickhouse.clickhouse_models import ClickHouseModel | ||||||
| from infi.clickhouse_orm.migrations import * | from infi.clickhouse_orm.migrations import * | ||||||
| from infi.clickhouse_orm.utils import import_submodules | from infi.clickhouse_orm.utils import import_submodules | ||||||
| 
 | 
 | ||||||
|  | @ -29,13 +32,13 @@ class Migration: | ||||||
|         :return: None |         :return: None | ||||||
|         """ |         """ | ||||||
|         db_router = lazy_class_import(config.DATABASE_ROUTER)() |         db_router = lazy_class_import(config.DATABASE_ROUTER)() | ||||||
|  |         database = database or connections[db_alias] | ||||||
| 
 | 
 | ||||||
|         for op in self.operations: |         for op in self.operations: | ||||||
|             model_class = getattr(op, 'model_class', None) |             model_class = getattr(op, 'model_class', None) | ||||||
|             hints = getattr(op, 'hints', {}) |             hints = getattr(op, 'hints', {}) | ||||||
| 
 | 
 | ||||||
|             if db_router.allow_migrate(db_alias, self.__module__, op, model=model_class, **hints): |             if db_router.allow_migrate(db_alias, self.__module__, op, model=model_class, **hints): | ||||||
|                 database = database or connections[db_alias] |  | ||||||
|                 op.apply(database) |                 op.apply(database) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -62,20 +65,17 @@ def migrate_app(app_label, db_alias, up_to=9999, database=None): | ||||||
|     if module_exists(migrations_package): |     if module_exists(migrations_package): | ||||||
|         database = database or connections[db_alias] |         database = database or connections[db_alias] | ||||||
| 
 | 
 | ||||||
|         applied_migrations = database._get_applied_migrations(migrations_package) |         applied_migrations = MigrationHistory.get_applied_migrations(db_alias, migrations_package) | ||||||
|         modules = import_submodules(migrations_package) |         modules = import_submodules(migrations_package) | ||||||
|         unapplied_migrations = set(modules.keys()) - set(applied_migrations) |         unapplied_migrations = set(modules.keys()) - applied_migrations | ||||||
| 
 | 
 | ||||||
|         for name in sorted(unapplied_migrations): |         for name in sorted(unapplied_migrations): | ||||||
|             print('Applying ClickHouse migration %s for app %s in database %s' % (name, app_label, db_alias)) |             print('Applying ClickHouse migration %s for app %s in database %s' % (name, app_label, db_alias)) | ||||||
|             migration = modules[name].Migration() |             migration = modules[name].Migration() | ||||||
|             migration.apply(db_alias, database=database) |             migration.apply(db_alias, database=database) | ||||||
| 
 | 
 | ||||||
|             # Ensure that table for migration storing is created |             migration_history_model = lazy_class_import(config.MIGRATION_HISTORY_MODEL) | ||||||
|             database.create_table(MigrationHistory) |             migration_history_model.set_migration_applied(db_alias, migrations_package, name) | ||||||
|             database.insert([ |  | ||||||
|                 MigrationHistory(package_name=migrations_package, module_name=name, applied=datetime.date.today()) |  | ||||||
|             ]) |  | ||||||
| 
 | 
 | ||||||
|             if int(name[:4]) >= up_to: |             if int(name[:4]) >= up_to: | ||||||
|                 break |                 break | ||||||
|  | @ -95,3 +95,56 @@ def clickhouse_migrate(sender, **kwargs): | ||||||
| 
 | 
 | ||||||
|     for db_alias in config.DATABASES: |     for db_alias in config.DATABASES: | ||||||
|         migrate_app(app_name, db_alias) |         migrate_app(app_name, db_alias) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class MigrationHistory(ClickHouseModel): | ||||||
|  |     """ | ||||||
|  |     A model for storing which migrations were already applied to database. | ||||||
|  |     This | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     db_alias = StringField() | ||||||
|  |     package_name = StringField() | ||||||
|  |     module_name = StringField() | ||||||
|  |     applied = DateField() | ||||||
|  | 
 | ||||||
|  |     engine = MergeTree('applied', ('db_alias', 'package_name', 'module_name')) | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def set_migration_applied(cls, db_alias, migrations_package, name):  # type: (str, str, str) -> None | ||||||
|  |         """ | ||||||
|  |         Sets migration apply status | ||||||
|  |         :param db_alias: Database alias migration is applied to | ||||||
|  |         :param migrations_package: Package migration is stored in | ||||||
|  |         :param name: Migration name | ||||||
|  |         :return: None | ||||||
|  |         """ | ||||||
|  |         db = cls.get_database(for_write=True) | ||||||
|  | 
 | ||||||
|  |         # Ensure that table for migration storing is created | ||||||
|  |         db.create_table(MigrationHistory) | ||||||
|  |         db.insert([ | ||||||
|  |             MigrationHistory(db_alias=db_alias, package_name=migrations_package, module_name=name, | ||||||
|  |                              applied=datetime.date.today()) | ||||||
|  |         ]) | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def get_applied_migrations(cls, db_alias, migrations_package):  # type: (str, str) -> Set[str] | ||||||
|  |         """ | ||||||
|  |         Returns applied migrations names | ||||||
|  |         :param db_alias: Database alias, to check | ||||||
|  |         :param migrations_package: Package name to check | ||||||
|  |         :return: Set of migration names | ||||||
|  |         """ | ||||||
|  |         qs = MigrationHistory.objects.filter(package_name=migrations_package, db_alias=db_alias).only('module_name') | ||||||
|  |         try: | ||||||
|  |             return set(obj.module_name for obj in qs) | ||||||
|  |         except ServerError as ex: | ||||||
|  |             # Database doesn't exist or table doesn't exist | ||||||
|  |             if ex.code in {81, 60}: | ||||||
|  |                 return set() | ||||||
|  |             raise ex | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def table_name(cls): | ||||||
|  |         return 'django_clickhouse_migrations' | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| from django.test import TestCase, override_settings | from django.test import TestCase, override_settings | ||||||
| from infi.clickhouse_orm.migrations import MigrationHistory | from django_clickhouse.migrations import MigrationHistory | ||||||
| 
 | 
 | ||||||
| from django_clickhouse.database import connections | from django_clickhouse.database import connections | ||||||
| from django_clickhouse.migrations import migrate_app | from django_clickhouse.migrations import migrate_app | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user