Handle for forward and backward data migration imports

This commit is contained in:
David Wobrock committed 2020-02-08 22:38:05 +01:00
1 parent 1e8fb95a8a
commit cb6961539c
2 files changed
+68 -1

No files matched your search

+46 -1
View File
@@ -421,5 +421,50 @@ class MigrationLinter(object):
else:
warning.append(issue)
# TODO: test if importing model directly or correctly using "get_model()"
# Detect wrong model imports
# Forward
issues = self.get_data_migration_model_import_issues(runpython.code)
for issue in issues:
if issue["code"] in self.exclude_migration_tests:
ignored.append(issue)
else:
error.append(issue)
# Backward
if runpython.reversible:
issues = self.get_data_migration_model_import_issues(runpython.reverse_code)
for issue in issues:
if issue and issue["code"] in self.exclude_migration_tests:
ignored.append(issue)
else:
error.append(issue)
return error, ignored, warning
@staticmethod
def get_data_migration_model_import_issues(code):
model_object_regex = re.compile(r"[^a-zA-Z]?([a-zA-Z0-9]+?)\.objects")
function_name = code.__name__
reverse_code_source = inspect.getsource(code)
called_models = model_object_regex.findall(reverse_code_source)
issues = []
for model in called_models:
has_get_model_call = (
re.search(
r"get_model\(.*?,.*?{}.+?\)".format(model), reverse_code_source
)
is not None
)
if not has_get_model_call:
issues.append(
{
"code": "DATA_MIGRATION_MODEL_IMPORT",
"msg": (
"'{}': Could not find an 'apps.get_model(\"...\", \"{}\")' "
"call. Importing the model directly is incorrect for "
"data migrations."
).format(function_name, model),
}
)
return issues
+22
View File
@@ -64,3 +64,25 @@ class DataMigrationDetectionTestCase(unittest.TestCase):
self.assertEqual(0, self.linter.nb_warnings)
self.assertEqual(1, self.linter.nb_erroneous)
self.assertTrue(self.linter.has_errors)
def test_missing_get_model_import(self):
def incorrect_importing_model_forward(apps, schema_editor):
from tests.test_project.app_data_migrations.models import MyModel
MyModel.objects.filter(id=1).first()
issues = MigrationLinter.get_data_migration_model_import_issues(
incorrect_importing_model_forward
)
self.assertEqual(1, len(issues))
def test_correct_get_model_import(self):
def correct_importing_model_forward(apps, schema_editor):
MyModel = apps.get_model("app_data_migrations", "MyModel")
MyModel.objects.filter(id=1).first()
issues = MigrationLinter.get_data_migration_model_import_issues(
correct_importing_model_forward
)
self.assertEqual(0, len(issues))