mirror of
https://github.com/jazzband/django-constance.git
synced 2026-03-16 22:40:24 +00:00
Better already migrated detection (#588)
This commit is contained in:
parent
a68bf903cf
commit
d624ee8730
2 changed files with 17 additions and 11 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -10,3 +10,4 @@ test.db
|
||||||
coverage.xml
|
coverage.xml
|
||||||
docs/_build
|
docs/_build
|
||||||
.idea
|
.idea
|
||||||
|
constance/_version.py
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import pickle
|
import pickle
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
|
@ -11,6 +12,16 @@ from constance.codecs import dumps
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def is_already_migrated(value):
|
||||||
|
try:
|
||||||
|
data = json.loads(value)
|
||||||
|
if isinstance(data, dict) and set(data.keys()) == {'__type__', '__value__'}:
|
||||||
|
return True
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def import_module_attr(path):
|
def import_module_attr(path):
|
||||||
package, module = path.rsplit('.', 1)
|
package, module = path.rsplit('.', 1)
|
||||||
return getattr(import_module(package), module)
|
return getattr(import_module(package), module)
|
||||||
|
|
@ -20,6 +31,7 @@ def migrate_pickled_data(apps, schema_editor) -> None: # pragma: no cover
|
||||||
Constance = apps.get_model('constance', 'Constance')
|
Constance = apps.get_model('constance', 'Constance')
|
||||||
|
|
||||||
for constance in Constance.objects.exclude(value=None):
|
for constance in Constance.objects.exclude(value=None):
|
||||||
|
if not is_already_migrated(constance.value):
|
||||||
constance.value = dumps(pickle.loads(b64decode(constance.value.encode()))) # noqa: S301
|
constance.value = dumps(pickle.loads(b64decode(constance.value.encode()))) # noqa: S301
|
||||||
constance.save(update_fields=['value'])
|
constance.save(update_fields=['value'])
|
||||||
|
|
||||||
|
|
@ -39,15 +51,8 @@ def migrate_pickled_data(apps, schema_editor) -> None: # pragma: no cover
|
||||||
for key in settings.CONFIG:
|
for key in settings.CONFIG:
|
||||||
prefixed_key = f'{_prefix}{key}'
|
prefixed_key = f'{_prefix}{key}'
|
||||||
value = _rd.get(prefixed_key)
|
value = _rd.get(prefixed_key)
|
||||||
if value is not None:
|
if value is not None and not is_already_migrated(value):
|
||||||
try:
|
|
||||||
redis_migrated_data[prefixed_key] = dumps(pickle.loads(value)) # noqa: S301
|
redis_migrated_data[prefixed_key] = dumps(pickle.loads(value)) # noqa: S301
|
||||||
except pickle.UnpicklingError as e:
|
|
||||||
if value.startswith(b'{"__'):
|
|
||||||
# Seems like we're facing already migrated data
|
|
||||||
# Might be related to defaults and when config was accessed while django inits for migration
|
|
||||||
continue
|
|
||||||
raise e
|
|
||||||
for prefixed_key, value in redis_migrated_data.items():
|
for prefixed_key, value in redis_migrated_data.items():
|
||||||
_rd.set(prefixed_key, value)
|
_rd.set(prefixed_key, value)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue