Мы используем установку с управляемыми и неуправляемыми таблицами в одной и той же базе данных, которая также может работать для вашего варианта использования:
У нас есть скрипт для создания тестовой базы данных из двух дампов: test_structure.sql
an test_fixtures.sql
.Первый содержит структуру базы данных в определенный момент времени, включая все неуправляемые таблицы.Последний содержит любые данные, которые могут вам понадобиться в неуправляемых таблицах во время тестирования, и содержимое таблицы django_migrations
.Мы сбрасываем test_fixtures.sql
, используя сгенерированный список COPY (SELECT * FROM {table}) TO STDOUT
;заявления, например: COPY (SELECT * FROM obs_00.django_migrations) TO STDOUT WITH NULL '--null--';
.
Выходные данные psql -c {copy_statement}
преобразуются в INSERT
операторы с использованием такой функции:
def csv2sqlinsert(table_name, data):
"""
Convert TSV output of COPY (SELECT * FROM {table}) TO STDOUT
to INSERT INTO {table} VALUES (), ()...();
"""
def is_int(val):
try:
return "{}".format(int(val)) == val
except ValueError:
return False
def column(data):
if data == "--null--":
return "null"
elif is_int(data):
return data
else:
return "'{}'".format(data.replace("'", "''")) # escape quotes
rows = [row.split("\t") for row in data.decode().split("\n") if len(row) > 1]
if len(rows) == 0:
return f"-- no data for {table_name}\n"
data = ",\n".join("({})".format(",".join(column(col) for col in row)) for row in rows)
ret = ""
ret += f"-- {table_name} ({len(rows)} rows)\n"
ret += f"INSERT INTO {table_name} VALUES\n{data};\n"
return ret
На самом деле эта функция более сложная, что также упрощает нашу геометрию postgis и обрезает большиетекстовые поля для экономии места.
создание тестовой базы данных
Определение имени тестовой базы данных в settings_test.py
:
DATABASES["default"].update({
"NAME": "django_test_db",
"TEST": {"NAME": "django_test_db",},
})
С двумя вышеуказанными файлами, (re)Создание тестовой базы данных выглядит следующим образом:
dropdb django_test_db
createdb django_test_db
psql -d django_test_db -f test_structure.sql
psql -d django_test_db < test_fixtures.sql
Теперь у нас есть состояние базы данных на момент создания дампа.Поскольку могут быть новые миграции, мы позволяем django мигрировать:
./manage.py migrate --settings=settings_test
Запуск тестов
Теперь мы можем запускать тесты, используя ./manage.py test --settings=settings_test
.Поскольку воссоздание базы данных при каждом запуске теста может занять значительное время, добавление --keepdb
сэкономит вам много времени в ожидании процедуры восстановления тестовой базы данных.
Мы изменили manage.py
вот такмы не можем забыть:
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "test":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings_test")
cmd = sys.argv + ["--keepdb"]
else:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
cmd = sys.argv
from django.core.management import execute_from_command_line
execute_from_command_line(cmd)