Fixed issue when INSTALLED_APPS settings contains AppConfig classes instead of module paths (#35)

Fixed issue when INSTALLED_APPS settings contains AppConfig classes instead of module paths
This commit is contained in:
M1ha Shvn 2021-10-01 17:38:10 +05:00 committed by GitHub
parent 0a7f0c1219
commit 12069db14e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 22 additions and 14 deletions

View File

@ -13,7 +13,7 @@ with open('requirements.txt') as f:
setup( setup(
name='django-clickhouse', name='django-clickhouse',
version='1.1.0', version='1.1.1',
packages=['django_clickhouse', 'django_clickhouse.management.commands'], packages=['django_clickhouse', 'django_clickhouse.management.commands'],
package_dir={'': 'src'}, package_dir={'': 'src'},
url='https://github.com/carrotquest/django-clickhouse', url='https://github.com/carrotquest/django-clickhouse',

View File

@ -3,7 +3,7 @@ Django command that applies migrations for ClickHouse database
""" """
import json import json
from django.conf import settings from django.apps import apps as django_apps
from django.core.management import BaseCommand, CommandParser from django.core.management import BaseCommand, CommandParser
from ...configuration import config from ...configuration import config
@ -25,10 +25,10 @@ class Command(BaseCommand):
parser.add_argument('--database', '-d', nargs='?', type=str, required=False, choices=config.DATABASES.keys(), parser.add_argument('--database', '-d', nargs='?', type=str, required=False, choices=config.DATABASES.keys(),
help='ClickHouse database alias key from CLICKHOUSE_DATABASES django setting.' help='ClickHouse database alias key from CLICKHOUSE_DATABASES django setting.'
' By defaults migrations are applied to all databases.') ' By default migrations are applied to all databases.')
def handle(self, *args, **options) -> None: def handle(self, *args, **options) -> None:
apps = [options['app_label']] if options['app_label'] else list(settings.INSTALLED_APPS) apps = [options['app_label']] if options['app_label'] else [app.name for app in django_apps.get_app_configs()]
databases = [options['database']] if options['database'] else list(config.DATABASES.keys()) databases = [options['database']] if options['database'] else list(config.DATABASES.keys())
kwargs = {'up_to': options['migration_number']} if options['migration_number'] else {} kwargs = {'up_to': options['migration_number']} if options['migration_number'] else {}

View File

@ -112,7 +112,7 @@ def clickhouse_migrate(sender, **kwargs):
return return
if kwargs.get('using', DJANGO_DEFAULT_DB_ALIAS) != DJANGO_DEFAULT_DB_ALIAS: if kwargs.get('using', DJANGO_DEFAULT_DB_ALIAS) != DJANGO_DEFAULT_DB_ALIAS:
# Не надо выполнять синхронизацию для каждого шарда. Только один раз. # Don't call sync for every database. Just once.
return return
app_name = kwargs['app_config'].name app_name = kwargs['app_config'].name
@ -124,9 +124,7 @@ def clickhouse_migrate(sender, **kwargs):
class MigrationHistory(ClickHouseModel): class MigrationHistory(ClickHouseModel):
""" """
A model for storing which migrations were already applied to database. A model for storing which migrations were already applied to database.
This
""" """
db_alias = StringField() db_alias = StringField()
package_name = StringField() package_name = StringField()
module_name = StringField() module_name = StringField()

View File

@ -3,7 +3,7 @@ import importlib
from typing import Type, Union from typing import Type, Union
from celery import shared_task from celery import shared_task
from django.conf import settings from django.apps import apps as django_apps
from infi.clickhouse_orm.utils import import_submodules from infi.clickhouse_orm.utils import import_submodules
from django_clickhouse.clickhouse_models import ClickHouseModel from django_clickhouse.clickhouse_models import ClickHouseModel
@ -32,8 +32,8 @@ def clickhouse_auto_sync() -> None:
:return: None :return: None
""" """
# Import all model modules # Import all model modules
for app in settings.INSTALLED_APPS: for app in django_apps.get_app_configs():
package_name = "%s.%s" % (app, config.MODELS_MODULE) package_name = "%s.%s" % (app.name, config.MODELS_MODULE)
try: try:
module = importlib.import_module(package_name) module = importlib.import_module(package_name)
if hasattr(module, '__path__'): if hasattr(module, '__path__'):

6
tests/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class UnitTestAppConfig(AppConfig):
name = 'tests'
verbose_name = "Unit test app"

View File

@ -56,7 +56,9 @@ LOGGING = {
INSTALLED_APPS = [ INSTALLED_APPS = [
"src", "src",
"tests"
# This app is included with config in order to test all is working fine here
"tests.apps.UnitTestAppConfig"
] ]
CLICKHOUSE_DATABASES = { CLICKHOUSE_DATABASES = {

View File

@ -63,15 +63,17 @@ class MigrateAppTest(TestCase):
@override_settings(CLICKHOUSE_MIGRATE_WITH_DEFAULT_DB=False) @override_settings(CLICKHOUSE_MIGRATE_WITH_DEFAULT_DB=False)
@mock.patch('django_clickhouse.management.commands.clickhouse_migrate.migrate_app', return_value=True) @mock.patch('django_clickhouse.management.commands.clickhouse_migrate.migrate_app', return_value=True)
class MigrateDjangoCommandTest(TestCase): class MigrateDjangoCommandTest(TestCase):
APP_LABELS = ('src', 'tests')
def setUp(self) -> None: def setUp(self) -> None:
self.cmd = Command() self.cmd = Command()
def test_handle_all(self, migrate_app_mock): def test_handle_all(self, migrate_app_mock):
self.cmd.handle(verbosity=3, app_label=None, database=None, migration_number=None) self.cmd.handle(verbosity=3, app_label=None, database=None, migration_number=None)
self.assertEqual(len(config.DATABASES.keys()) * len(settings.INSTALLED_APPS), migrate_app_mock.call_count) self.assertEqual(len(config.DATABASES.keys()) * len(self.APP_LABELS), migrate_app_mock.call_count)
for db_alias in config.DATABASES.keys(): for db_alias in config.DATABASES.keys():
for app_label in settings.INSTALLED_APPS: for app_label in self.APP_LABELS:
migrate_app_mock.assert_any_call(app_label, db_alias, verbosity=3) migrate_app_mock.assert_any_call(app_label, db_alias, verbosity=3)
def test_handle_app(self, migrate_app_mock): def test_handle_app(self, migrate_app_mock):
@ -85,7 +87,7 @@ class MigrateDjangoCommandTest(TestCase):
self.cmd.handle(verbosity=3, database='default', app_label=None, migration_number=None) self.cmd.handle(verbosity=3, database='default', app_label=None, migration_number=None)
self.assertEqual(len(settings.INSTALLED_APPS), migrate_app_mock.call_count) self.assertEqual(len(settings.INSTALLED_APPS), migrate_app_mock.call_count)
for app_label in settings.INSTALLED_APPS: for app_label in self.APP_LABELS:
migrate_app_mock.assert_any_call(app_label, 'default', verbosity=3) migrate_app_mock.assert_any_call(app_label, 'default', verbosity=3)
def test_handle_app_and_database(self, migrate_app_mock): def test_handle_app_and_database(self, migrate_app_mock):