mirror of
https://github.com/carrotquest/django-clickhouse.git
synced 2024-11-25 10:33:47 +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