2014-10-02 16 views
11

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?

+1

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. –

+0

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

+1

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ụ. –

Trả lời

1

Một điều hữu ích có thể là công cụ ORN bất khả tri có thể là "thay vì" trình kích hoạt. Ví dụ, bạn có thể nắm bắt một sự kiện trước khi cập nhật và mở một số phiên bản với dữ liệu mới được cập nhật.

Đối với postgresql, chúng được chi tiết here.

Tất nhiên, bạn sẽ phải có thay đổi về mô hình (trên PK, v.v.). Ngoài ra, nó sẽ là giá trị nghiên cứu tác động hiệu suất, vì bạn có thể sẽ phải có một truy vấn đệ quy để lấy "phiên bản mới nhất" (thông qua một lớp xem, hoặc trong thuật toán giả kim thuật sql ở đâu điều khoản/v.v ...).)

0

Vì điều đó nghe có vẻ điên rồ với bạn, thực tế có thể tốt hơn nếu bạn sử dụng một loại cơ sở dữ liệu khác. Bạn có biết về Datomic? không. Một trong những khác biệt cơ bản giữa RDBMS truyền thống và loại hệ thống này là không có bản cập nhật tại chỗ, đó là cách RDBMS cập nhật các tệp trên đĩa. Thay vào đó, tất cả mọi thứ được phiên bản, và bạn có thể quay trở lại thông qua tất cả các phiên bản trước của cơ sở dữ liệu cho mọi thay đổi cho mỗi tài nguyên. Ngoài ra, bạn có thể dễ dàng xem trạng thái của toàn bộ cơ sở dữ liệu tại một thời điểm cụ thể trong thời gian, bằng cách chỉ cần chuyển thời gian quan tâm dưới dạng tham số.Có rất nhiều lợi ích thú vị khác, và tôi khuyên bạn nên xem xét một số cuộc đàm phán của Rich Hickey về nó, ví dụ this one. Đó chắc chắn là một cách tiếp cận cơ bản khác với những gì bạn đang cố gắng, nhưng người ta phải cân nhắc xem liệu nỗ lực đó có được kiên trì bằng cách chiến đấu chống lại các công cụ ở mọi bước đường hay không, sử dụng chúng theo cách mà họ thực sự không được thiết kế (RDBMS, ORM, trình quản lý di chuyển, ...). Thay vào đó, bạn có thể đẩy độ phức tạp đó xuống một lớp và để một loại DB khác xử lý nó cho bạn.

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