SQLAlchemy, Wyczyść zawartość bazy danych, ale nie upuść schematu

Rozwijam aplikację Pylons, która jest oparta na bazie exisitng, więc używam reflection. Mam plik SQL ze schematem, którego użyłem do utworzenia testowej bazy danych. Dlatego nie mogę po prostu użyć drop_all i create_all.

Chciałbym napisać kilka testów jednostkowych i stanąłem przed problemem wyczyszczenia zawartości bazy danych po każdym teście. Chcę tylko wymazać wszystkie dane, ale pozostawić tabele nienaruszone. Czy to możliwe?

Aplikacja korzysta z Postgres i to jest to, co musi być stosowany również do badań.

Author: Juliusz Gonera, 2011-01-21

3 answers

Zapytałem o to samo na SQLAlchemy Google group, i mam przepis, który wydaje się działać dobrze(wszystkie moje tabele są opróżnione). Zobacz wątek w celach informacyjnych.

Mój kod (fragment) wygląda tak:

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()

Edit: zmodyfikowałem kod, aby usuwać tabele w odwrotnej kolejności; podobno powinno to zapewnić, że dzieci są usuwane przed rodzicami.

 57
Author: aknuds1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-20 12:41:11

Dla PostgreSQL używając 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()

Uwaga: RESTART IDENTITY; zapewnia również reset wszystkich sekwencji. Jest to jednak wolniejsze od przepisu DELETE autorstwa @aknuds1 o 50%.

Innym przepisem jest zrzucenie wszystkich tabel najpierw, a następnie odtworzyć je. To jest wolniejsze o kolejne 50%:

Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
 16
Author: kolypto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-09 16:59:46

Jak o użyciu truncate:

TRUNCATE [TABLE ] name [,...]

(http://www.postgresql.org/docs/8.4/static/sql-truncate.html )

Spowoduje to usunięcie wszystkich rekordów w tabeli, ale pozostawi schemat w takcie.

 -3
Author: Joe L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 20:40:37