SQLAlchemy, очистить содержимое базы данных, но не отбрасывать схему
Я разрабатываю приложение Pylons, основанное на базе exisitng, поэтому я использую отражение. У меня есть файл SQL со схемой, которую я использовал для создания тестовой базы данных. Поэтому я не могу просто использовать drop_all
и create_all
.
Я хотел бы написать некоторые модульные тесты, и я столкнулся с проблемой очистки содержимого базы данных после каждого теста. Я просто хочу стереть все данные, но оставил таблицы неповрежденными. Возможно ли это?
Приложение использует Postgres, и это то, что должно использоваться также для тестов.
Ответы
Ответ 1
Я спросил об этом же в группе SQLAlchemy Google, и у меня есть рецепт, который, кажется, работает хорошо (все мои таблицы опустели). См. поток для справки.
Мой код (выдержка) выглядит следующим образом:
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
Для 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;
гарантирует, что все последовательности будут reset. Однако это медленнее, чем рецепт DELETE
by @aknuds1 на 50%.
Другой рецепт - сначала отбросить все таблицы, а затем воссоздать их. Это медленнее на 50%:
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
Ответ 3
Как насчет использования truncate:
TRUNCATE [TABLE] имя [,...]
(http://www.postgresql.org/docs/8.4/static/sql-truncate.html)
Это приведет к удалению всех записей в таблице, но оставить схему в такте.