I found a similar thread here Backwards compatible migrations
I’m looking for advice on how data addition/deletion are typically handled with migrations.
I’m building a feature with the following scenarios
- some models have only new data to be inserted
- some models have changes like adding/deleting fields
- some models are new.
In all cases I need to insert new data into the table.
I identified 2 approaches to doing this. I have illustrated the approaches below with MWEs.
Approach one
Include the data inside the migration script with a function to reverse the data insertion.
models.py
from django.db import models
class NewModel(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
migration file
# migrations/000X_create_and_insert_initial_data.py
from django.db import migrations, models
import json
import os
def load_initial_data(apps, schema_editor):
NewModel = apps.get_model('myapp', 'NewModel')
# Load data from JSON file
data_file_path = os.path.join(os.path.dirname(__file__), '..', 'data', 'initial_data.json')
with open(data_file_path, 'r') as f:
initial_data = json.load(f)
# Insert initial data
for data in initial_data:
NewModel.objects.create(**data)
def remove_initial_data(apps, schema_editor):
NewModel = apps.get_model('myapp', 'NewModel')
# Load data from JSON file
data_file_path = os.path.join(os.path.dirname(__file__), '..', 'data', 'initial_data.json')
with open(data_file_path, 'r') as f:
initial_data = json.load(f)
# Collect names to remove
initial_data_names = [item['name'] for item in initial_data]
NewModel.objects.filter(name__in=initial_data_names).delete()
# Drop the NewModel table
schema_editor.delete_model(NewModel)
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_previous_migration'), # Replace with your actual previous migration
]
operations = [
migrations.CreateModel(
name='NewModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('description', models.TextField()),
],
),
migrations.RunPython(load_initial_data, reverse_code=remove_initial_data),
]
Approach Two
Use raw sql to insert/update/delete from the database tables. (Please ignore syntax errors here)
INSERT INTO TABLE mytable VALUES...
-- DROP TABLE
-- ALTER TABLE delete column
-- DELETE from table where ... ----> for deleting just new records which were inserted.
I’m trying to understand what’s the recommended practice in these scenarios and how future data additions should be handled. I would appreciate if the data migration is reversible easily since this is a critical application so we would like to avoid data inconsistencies if possible/noticed.