Better already migrated detection (#588)

This commit is contained in:
Alexandr Artemyev 2024-09-17 14:59:11 +05:00 committed by GitHub
parent a68bf903cf
commit d624ee8730
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 11 deletions

1
.gitignore vendored
View file

@ -10,3 +10,4 @@ test.db
coverage.xml
docs/_build
.idea
constance/_version.py

View file

@ -1,3 +1,4 @@
import json
import logging
import pickle
from base64 import b64decode
@ -11,6 +12,16 @@ from constance.codecs import dumps
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):
package, module = path.rsplit('.', 1)
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')
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.save(update_fields=['value'])
@ -39,15 +51,8 @@ def migrate_pickled_data(apps, schema_editor) -> None: # pragma: no cover
for key in settings.CONFIG:
prefixed_key = f'{_prefix}{key}'
value = _rd.get(prefixed_key)
if value is not None:
try:
if value is not None and not is_already_migrated(value):
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():
_rd.set(prefixed_key, value)