Я разрабатываю приложение Pylons, основанное на существующей базе данных, поэтому я использую отражение. У меня есть файл SQL со схемой, которую я использовал для создания своей тестовой базы данных. Вот почему я не могу просто использовать drop_all и create_all.
Я хотел бы написать несколько модульных тестов и столкнулся с проблемой очистки содержимого базы данных после каждого теста. Я просто хочу стереть все данные, но оставить таблицы нетронутыми. Это возможно?
Приложение использует Postgres, и это то, что нужно также использовать для тестов.
Ответ 1 · рейтинг 60 · aknuds1
Я спросил о том же в группе Google SQLAlchemy и получил рецепт, который, похоже, работает хорошо (все мои таблицы опустошены). См. ветку для справки.
Мой код (отрывок) выглядит так:
import contextlib
from sqlalchemy import MetaData
meta = MetaData()
with contextlib.closing(engine.connect()) as con:
trans = con.begin()
for table in reversed(meta.sorted_tables):
con.execute(table.delete())
trans.commit()
Изменить: я изменил код, чтобы удалить таблицы в обратном порядке; якобы это должно гарантировать, что дети будут удалены раньше родителей.
Ответ 2 · рейтинг 16 · kolypto
Для PostgreSQL с использованием TRUNCATE:
with contextlib.closing(engine.connect()) as con:
trans = con.begin()
con.execute('TRUNCATE {} RESTART IDENTITY;'.format(
','.join(table.name
for table in reversed(Base.metadata.sorted_tables))))
trans.commit()
Примечание: RESTART IDENTITY; гарантирует, что все последовательности также будут сброшены. Однако это медленнее, чем DELETE рецепт @ aknuds1 на 50%.
Другой рецепт - сначала удалить все таблицы, а затем воссоздать их. Это медленнее еще на 50%:
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)