我正在開發基於存在數據庫的Pylons應用程序,所以我正在使用反射。我有一個SQL文件,其中包含我用來創建測試數據庫的模式。這就是爲什麼我不能簡單地使用drop_all
和create_all
。SQLAlchemy,清除數據庫內容但不刪除模式
我想寫一些單元測試,我面臨每次測試後清除數據庫內容的問題。我只是想刪除所有的數據,但保持表格不變。這可能嗎?
該應用程序使用Postgres,這也是必須使用的測試。
我正在開發基於存在數據庫的Pylons應用程序,所以我正在使用反射。我有一個SQL文件,其中包含我用來創建測試數據庫的模式。這就是爲什麼我不能簡單地使用drop_all
和create_all
。SQLAlchemy,清除數據庫內容但不刪除模式
我想寫一些單元測試,我面臨每次測試後清除數據庫內容的問題。我只是想刪除所有的數據,但保持表格不變。這可能嗎?
該應用程序使用Postgres,這也是必須使用的測試。
我在SQLAlchemy的Google小組上詢問過同樣的事情,並且我看到了一個看起來很好的配方(我所有的表都被清空了)。請參閱the thread以供參考。
我的代碼(節選)看起來是這樣的:
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()
編輯:我修改了代碼,刪除以相反的順序表;據說這應該確保孩子在父母面前被刪除。
如何使用截斷:
TRUNCATE [TABLE]名[,...]
(http://www.postgresql.org/docs/8.4/static/sql-truncate.html)
這將刪除所有表中的記錄,但離開架構中圓通。
這將是好的,但我怎麼能在SQLAlchemy中使用它?對於meta.Base.metadata.tables.keys()中的表:meta.Session.execute('truncate%s'%table); meta.Session.commit()`導致這樣的錯誤消息:「InternalError:(InternalError)當前事務中止,命令被忽略,直到事務塊結束 'truncate data.subkeywords'{}」 – 2011-01-21 21:32:46
我通過執行`truncate% s級聯「,但它很痛苦地緩慢。每個單元測試後運行速度太慢... – 2011-01-21 22:03:44
問題是要求sqlalchemy,而不是sql。 – lnhubbell 2015-11-24 18:56:35
對於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;
確保所有的序列被複位爲好。不過,這比@ aknuds1的DELETE
配方慢50%。
另一個方法是首先刪除所有表,然後重新創建它們。這比另一個50%慢:
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
您應該使用事務。 http://docs.sqlalchemy.org/en/rel_0_7/orm/session.html#joining-a-session-into-an-external-transaction – charlax 2012-09-12 09:35:54