W Django 2.1 chciałem załadować niektóre modele (na przykład nazwy krajów) z danymi początkowymi.
Ale chciałem, żeby stało się to automatycznie zaraz po wykonaniu początkowych migracji.
Pomyślałem więc, że byłoby wspaniale mieć sql/folder w każdej aplikacji, który wymagałby załadowania danych początkowych.
Następnie w tym sql/folderze miałbym .sqlpliki z wymaganymi plikami DML, aby załadować dane początkowe do odpowiednich modeli, na przykład:
INSERT INTO appName_modelName(fieldName)
VALUES
("country 1"),
("country 2"),
("country 3"),
("country 4");
Aby być bardziej opisowym, tak wyglądałaby aplikacja zawierająca sql/folder:

Znalazłem również przypadki, w których potrzebowałem sqlskryptów do wykonania w określonej kolejności. Postanowiłem więc poprzedzić nazwy plików kolejnym numerem, jak widać na powyższym obrazku.
Potem potrzebowałem sposobu, aby automatycznie załadować wszystkie SQLsdostępne w dowolnym folderze aplikacji, wykonując python manage.py migrate.
Utworzyłem więc inną aplikację o nazwie, initial_data_migrationsa następnie dodałem tę aplikację do listy INSTALLED_APPSw settings.pypliku. Następnie utworzyłem migrationsfolder w środku i dodałem plik o nazwie run_sql_scripts.py( co w rzeczywistości jest niestandardową migracją ). Jak widać na poniższym obrazku:

Stworzyłem run_sql_scripts.pytak, aby zadbał o uruchomienie wszystkich sqlskryptów dostępnych w ramach każdej aplikacji. Ten jest następnie odpalany, gdy ktoś biegnie python manage.py migrate. Ten niestandardowy migrationdodaje również zaangażowane aplikacje jako zależności, w ten sposób próbuje uruchomić sqlinstrukcje dopiero po wykonaniu 0001_initial.pymigracji przez wymagane aplikacje (nie chcemy próbować uruchamiać instrukcji SQL na nieistniejącej tabeli).
Oto źródło tego skryptu:
import os
import itertools
from django.db import migrations
from YourDjangoProjectName.settings import BASE_DIR, INSTALLED_APPS
SQL_FOLDER = "/sql/"
APP_SQL_FOLDERS = [
(os.path.join(BASE_DIR, app + SQL_FOLDER), app) for app in INSTALLED_APPS
if os.path.isdir(os.path.join(BASE_DIR, app + SQL_FOLDER))
]
SQL_FILES = [
sorted([path + file for file in os.listdir(path) if file.lower().endswith('.sql')])
for path, app in APP_SQL_FOLDERS
]
def load_file(path):
with open(path, 'r') as f:
return f.read()
class Migration(migrations.Migration):
dependencies = [
(app, '__first__') for path, app in APP_SQL_FOLDERS
]
operations = [
migrations.RunSQL(load_file(f)) for f in list(itertools.chain.from_iterable(SQL_FILES))
]
Mam nadzieję, że ktoś uzna to za pomocne, działało dobrze dla mnie !. Jeśli masz jakieś pytania, daj mi znać.
UWAGA: To może nie być najlepsze rozwiązanie, ponieważ dopiero zaczynam pracę z django, jednak nadal chciałem się z wami podzielić tym "Jak to zrobić", ponieważ nie znalazłem zbyt wielu informacji podczas wyszukiwania go w Google.