Skip to content

Commit

Permalink
Better already migrated detection
Browse files Browse the repository at this point in the history
  • Loading branch information
Mogost committed Sep 16, 2024
1 parent a68bf90 commit d972726
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ test.db
coverage.xml
docs/_build
.idea
constance/_version.py
25 changes: 16 additions & 9 deletions constance/migrations/0003_drop_pickle.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import logging
import pickle
from base64 import b64decode
Expand All @@ -11,6 +12,19 @@
logger = logging.getLogger(__name__)


def is_already_migrated(value):
migrated_shape = {'__type__', '__value__'}
try:
data = json.loads(value)

Check warning on line 18 in constance/migrations/0003_drop_pickle.py

View check run for this annotation

Codecov / codecov/patch

constance/migrations/0003_drop_pickle.py#L16-L18

Added lines #L16 - L18 were not covered by tests
if (isinstance(data, list) and all(set(item.keys()) == migrated_shape for item in data)) or (
isinstance(data, dict) and set(data.keys()) == migrated_shape
):
return True
except (json.JSONDecodeError, TypeError):
return False
return False

Check warning on line 25 in constance/migrations/0003_drop_pickle.py

View check run for this annotation

Codecov / codecov/patch

constance/migrations/0003_drop_pickle.py#L22-L25

Added lines #L22 - L25 were not covered by tests


def import_module_attr(path):
package, module = path.rsplit('.', 1)
return getattr(import_module(package), module)
Expand Down Expand Up @@ -39,15 +53,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:
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
if value is not None and not is_already_migrated(value):
redis_migrated_data[prefixed_key] = dumps(pickle.loads(value)) # noqa: S301
for prefixed_key, value in redis_migrated_data.items():
_rd.set(prefixed_key, value)

Expand Down

0 comments on commit d972726

Please sign in to comment.