2011-01-21 30 views
38

Tôi đang phát triển ứng dụng Giá treo dựa trên cơ sở dữ liệu exisitng, vì vậy tôi đang sử dụng phản chiếu. Tôi có một tệp SQL với lược đồ mà tôi đã sử dụng để tạo cơ sở dữ liệu thử nghiệm của mình. Đó là lý do tại sao tôi không thể chỉ đơn giản là sử dụng drop_allcreate_all.SQLAlchemy, nội dung cơ sở dữ liệu rõ ràng nhưng không bỏ lược đồ

Tôi muốn viết một số bài kiểm tra đơn vị và tôi phải đối mặt với vấn đề xóa nội dung cơ sở dữ liệu sau mỗi lần kiểm tra. Tôi chỉ muốn xóa tất cả dữ liệu nhưng để nguyên bảng. Điều này có thể không?

Ứng dụng sử dụng Postgres và đây cũng là những gì phải được sử dụng để thử nghiệm.

+0

Bạn nên sử dụng giao dịch. http://docs.sqlalchemy.org/en/rel_0_7/orm/session.html#joining-a-session-into-an-external-transaction – charlax

Trả lời

40

Tôi đã hỏi về điều tương tự trên nhóm GoogleAlchemy Google và tôi nhận được công thức hoạt động tốt (tất cả các bảng của tôi đều trống). Xem the thread để tham khảo.

Mã của tôi (trích đoạn) trông như thế này:

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: Tôi sửa đổi mã để xóa bảng trong thứ tự ngược lại; được cho là điều này nên đảm bảo rằng trẻ em bị xóa trước cha mẹ.

+4

Dường như hoạt động! Cảm ơn bạn. Mã chính xác tôi sử dụng trong giá treo là: 'cho bảng đảo ngược (meta.Base.metadata.sorted_tables): meta.Session.execute (table.delete()); meta.Session.commit() ' –

+5

'Động cơ' đến từ đâu? Và 'contextlib'? Đó có phải là thư viện chuẩn không? Câu trả lời này sẽ tốt hơn nếu việc nhập khẩu hoàn tất. – Zelphir

0

Làm thế nào về việc sử dụng truncate:

TRUNCATE [TABLE] tên [...]

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

này sẽ xóa tất cả các bản ghi trong bảng, nhưng rời khỏi lược đồ trong khéo léo.

+1

Điều này sẽ ổn nhưng làm cách nào tôi có thể sử dụng nó trong SQLAlchemy? 'cho bảng trong meta.Base.metadata.tables.keys(): meta.Session.execute ('truncate% s'% table); meta.Session.commit() 'gây ra thông báo lỗi như vậy:" InternalError: (InternalError) giao dịch hiện tại bị hủy bỏ, lệnh bị bỏ qua cho đến khi kết thúc khối giao dịch 'cắt ngắn dữ liệu.subkeywords' {} " –

+1

Tôi đã sửa nó bằng cách thực hiện' truncate% s cascade' nhưng nó rất chậm. Quá chậm để chạy sau mỗi lần kiểm tra đơn vị ... –

+2

Câu hỏi đặt ra là yêu cầu sqlalchemy chứ không phải sql. – lnhubbell

7

Đối với PostgreSQL sử dụng 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() 

Lưu ý: RESTART IDENTITY; đảm bảo rằng tất cả các chuỗi được thiết lập lại là tốt. Tuy nhiên, điều này chậm hơn công thức DELETE bởi @ aknuds1 50%.

Công thức khác là bỏ tất cả các bảng trước và sau đó tạo lại chúng. Số tiền này chậm hơn 50% khác:

Base.metadata.drop_all(bind=engine) 
Base.metadata.create_all(bind=engine) 
+0

'metadata.Base.metadata.drop_all (bind = engine)' đưa ra lỗi 'AttributeError: đối tượng 'MetaData' không có thuộc tính 'Base'' – danio

Các vấn đề liên quan