Tôi muốn triển khai lại một số mô hình SQLAlchemy hiện tại của mình trong kho dữ liệu phụ; append-only nghĩa là đối tượng chỉ được cập nhật với các câu lệnh INSERT, không sử dụng các câu lệnh UPDATE hoặc DELETE.Cách triển khai mô hình được phiên bản chỉ chắp thêm trong SQLAlchemy
Các câu lệnh UPDATE và DELETE sẽ được thay thế bằng một INSERT khác làm tăng phiên bản. Sẽ có một lá cờ is_deleted
và thay vì DELETE, một phiên bản mới với is_deleted=True
sẽ được tạo:
id | version | is_deleted | name | description ...
---- --------- ------------ ----------- ---------------
1 | 1 | F | Fo | Text text text.
1 | 2 | F | Foo | Text text text.
2 | 1 | F | Bar | null
1 | 3 | T | Foo | Text text text.
Bên cạnh đó,
- Tất cả các câu SELECT sẽ cần phải được viết lại để chỉ số phiên bản tối đa cho mỗi id, như được mô tả trong câu hỏi này: PostgreSQL - fetch the row which has the Max value for a column
- Tất cả (duy nhất) chỉ mục cần phải được viết lại thành duy nhất bằng khóa chính "id", vì mỗi id có thể có nhiều hơn một lần.
tôi biết làm thế nào để giải quyết hầu hết các vấn đề, nhưng tôi phải vật lộn với các móc sự kiện trong SQLAlchemy rằng sẽ xử lý một số điều mà cần phải được thực hiện trên bản cập nhật & xóa.
Tài liệu SQLAlchemy đã có một số ví dụ cơ bản về phiên bản. Ví dụ versioned rows đến gần với những gì tôi muốn, nhưng chúng không xử lý (1) xóa và (2) các mối quan hệ khóa ngoại.
(1) Xóa. Tôi biết có một trường session.deleted
và tôi sẽ lặp lại theo cách tương tự như cách session.dirty
được lặp lại trong ví dụ versioned_rows.py — nhưng làm cách nào để bỏ mục khỏi danh sách cần xóa & tạo một mục mới?
(2) Ví dụ trên chỉ đề cập đến mối quan hệ cha-con và cách nó thực hiện (hết hạn mối quan hệ) dường như yêu cầu mã tùy chỉnh cho từng mô hình. (2.1) Có cách nào để làm cho điều này linh hoạt hơn không? (2.2) có thể cấu hình SQLAlchemy's relationship()
để trả về đối tượng với tối đa (phiên bản) cho một khóa ngoại được không?
Cụm từ bạn đang tìm kiếm là "xóa mềm". Tôi không thực sự biết SQLAlchemy, nhưng có lẽ điều đó sẽ giúp bạn. Cá nhân tôi có thể làm điều này với các trigger ở phía cơ sở dữ liệu. –
Cảm ơn - Tôi đã tìm thấy điều này khi xóa phần mềm, giúp phần đầu tiên của câu hỏi của tôi http://stackoverflow.com/questions/23198801/sqlalchemy-using-aliased-in-query-with-custom-primaryjoin-relationship Sử dụng cơ sở dữ liệu trình kích hoạt không phải là một tùy chọn cho tôi vì mô hình của tôi thay đổi thường xuyên và trình kích hoạt không được xử lý tốt bởi các công cụ di chuyển như alembic. – lyschoening
Câu hỏi tò mò, tôi cũng muốn xem một số ví dụ về việc xử lý vấn đề này. Về liên kết đến tối đa (phiên bản), cách tốt hơn có thể là không có số phiên bản so với phiên bản Head để bạn có thể tham gia trực tiếp vào bản ghi mới nhất (phiên bản == Không). Dữ liệu có cần phải ở trong cùng một bảng không? Chỉ cần tự hỏi nếu hệ thống các đối tượng versioning (tạo ra một bảng thứ hai, blah_history) có thể đơn giản hóa mọi thứ http://docs.sqlalchemy.org/en/latest/orm/examples.html#versioning-objects. Nó cũng xử lý xóa trong đó toàn bộ lịch sử phiên bản có sẵn trong bảng phụ. –