Django migrazione

Migrazioni e Fixtures

Moreno Iacomino

Creazione di fixtures per popolare i contenuti di tabelle tramite migrazioni

A volte è utile pre compilare il database con dati hardcoded quando si configura un'app per la prima volta.
È possibile fornire i dati iniziali con le migrazioni o le fixture

Cosa è una fixture?

Una fixture è una raccolta di dati che Django sa come importare in un database.
Il modo più semplice per creare una fixture se hai già dei dati è usare il comando manage.py dumpdata.

Oppure puoi scrivere le fixtures a mano; le fixture possono essere scritte come documenti JSON, XML o YAML (con PyYAML installato). La documentazione Django sulla serializzazione contiene ulteriori dettagli su ciascuno di questi formati supportati.


Iniziamo!

1. Creare una cartella 'fixtures' nella root della app Sull'admin Django,
2. Inserire i contenuti che si vogliono portare nelle migrazioni
3. 
Per ogni modello interessato, eseguire questo comando per generare un json di contenuti:

./manage.py dumpdata nome_app.NomeModello > nome_app/fixtures/nome_modello.json 

  4. Creare una migrazione vuota eseguendo il comando

./manage.py makemigrations nome_app --empty 

   5. Incollare il seguente codice nel file di migrazione generato

# Generated by Django 2.2.4 on 2022-06-15 10:51

import os
from django.db import migrations
from django.core import serializers

fixture_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../fixtures'))

def genera_load_fixture(fixture_filename):
def load_fixture(apps, schema_editor):
fixture_file = os.path.join(fixture_dir, fixture_filename)
fixture = open(fixture_file, 'rb')
objects = serializers.deserialize('json', fixture, ignorenonexistent=True)
for obj in objects:
obj.save()
fixture.close()
return load_fixture

def generate_unload_fixture(model_name):
def unload_fixture(apps, schema_editor):
Model = apps.get_model("controllo_fatture_terminal", model_name)
Model.objects.all().delete()
return unload_fixture

class Migration(migrations.Migration):
# questa parte dovrebbe essere già scritta correttamente da Django col comando makemigrations
dependencies = [
('nome_app', 'ultima_migrazione_creata_prima_di_questa'),
]
# creare in operations una entry per ogni modello modificato, cambiando il nome del file json
# passato come parametroalla load_fixture e il nome del modello passato come parametro alla
# unload_fixture
operations = [
migrations.RunPython(genera_load_fixture('nome_modello.json'),
reverse_code=generate_unload_fixture("NomeModello")),
]


Questi file verranno versionati insieme a tutti gli altri file, per cui in fase di messa in produzione non dovrà essere fatto un ulteriore Data Entry, ma eseguendo le migrazioni del DB di produzione, avremo in automatico già anche i dati popolati.

Segui il nostro blog: guide, consigli e segreti a prova di bug! 🐞