I have created a post_migrate with the goal to sync all the data inside the table whenever a migration runs. This is the snippet of the post_migrate file:
# signals.py
@receiver(post_migrate)
def full_sync_if_model_change(plan, **kwargs):
if plan:
models_set = set()
for file, _ in plan:
for model in file.operations:
try:
model = SyncModel.objects.get(
app_name=file.app_label, model_name=model.model_name
)
models_set.add(model)
except ObjectDoesNotExist:
pass
print(models_set)
if models_set:
for model in models_set:
model.set_full_sync()
run_update_sync(model, False)
return
However, when I run a migration, it is called 6 times; as you can see in the output of migration:
evandro@evandro-340XAA-350XAA-550XAA:~/Desktop/.../test_service$ python3 manage.py migrateOperations to perform:
Apply all migrations: admin, auth, contenttypes, django_cron, lakehouse_sync, sessions, test_models
Running migrations:
Applying test_models.0019_auto_20211026_2052... OK
set()
set()
set()
set()
set()
set()
I'll add here also the apps file:
class LakeSyncConfig(AppConfig):
name = "lake_sync"
def ready(self):
"""Import signals"""
import lakehouse_sync.core.delete_action
from . import signals
I have no idea what to do, I tried to add this return statement, but it doesn't work, because the function is called all the time.
CodePudding user response:
The post_migrate
signal is sent once for every app migrated, even if there were no changes. Pass the sender
parameter when connecting your signal to only run your function once when your app has migrated
def full_sync_if_model_change(plan, **kwargs):
...
class LakeSyncConfig(AppConfig):
name = "lake_sync"
def ready(self):
post_migrate.connect(full_sync_if_model_change, sender=self)