2012-07-21 42 views
5

Câu hỏi của tôi là, cách tốt nhất để tạo một thực thể mô hình mới là gì và sau đó đọc nó ngay sau đó. Ví dụ,Làm cách nào để tạo một thực thể mô hình mới, sau đó đọc nó ngay sau đó?

class LeftModel(ndb.Model): 
    name = ndb.StringProperty(default = "John") 
    date = ndb.DateTimeProperty(auto_now_add=True) 

class RightModel(ndb.Model): 
    left_model = ndb.KeyProperty(kind=LeftModel) 
    interesting_fact = ndb.StringProperty(default = "Nothing") 

def do_this(self): 
    # Create a new model entity 
    new_left = LeftModel() 
    new_left.name = "George" 
    new_left.put() 

    # Retrieve the entity just created 
    current_left = LeftModel.query().filter(LeftModel.name == "George").get() 

    # Create a new entity which references the entity just created and retrieved 
    new_right = RightModel() 
    new_right.left_model = current_left.key 
    new_right.interesting_fact = "Something" 
    new_right.put() 

này khá thường xuyên ném một ngoại lệ như:

AttributeError: 'NoneType' object has no attribute 'key' 

Tức là việc truy xuất thực thể LeftModel mới không thành công. Tôi đã phải đối mặt với vấn đề này một vài lần với appengine và giải pháp của tôi luôn luôn là một chút hacky. Thông thường tôi chỉ cần đặt tất cả mọi thứ trong một thử ngoại trừ hoặc một vòng lặp while cho đến khi thực thể được truy xuất thành công. Làm thế nào tôi có thể đảm bảo rằng thực thể mô hình luôn được truy xuất mà không phải chạy các rủi ro của vòng lặp vô hạn (trong trường hợp vòng lặp while) hoặc làm rối tung mã của tôi (trong trường hợp thử các câu lệnh ngoại trừ)?

+1

chỉ cần đặt khóa cho LeftModel khi tạo thay vì sử dụng khóa được tạo tự động. –

+1

+1 vấn đề được nêu rõ – msw

Trả lời

9

Tại sao bạn cố tìm nạp đối tượng qua truy vấn ngay sau khi bạn đã thực hiện put().

Bạn nên sử dụng new_left bạn vừa tạo ra và ngay lập tức gán nó vào new_right như trong new_right.left_model = current_left.key

Lý do bạn không thể truy vấn ngay lập tức là vì HRD sử dụng một mô hình thống nhất cuối cùng, có nghĩa là bạn kết quả của giao dịch thỏa thuận sẽ có thể nhìn thấy được. Nếu bạn muốn có kết quả nhất quán thì bạn phải thực hiện các truy vấn tổ tiên và điều này ngụ ý một tổ tiên trong khóa về tạo. Do bạn đang tạo ra một cây, điều này có lẽ không thực tế. Hãy đọc về cấu trúc dữ liệu cho tính nhất quán mạnh https://developers.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency

Tôi không thấy lý do nào khiến bạn không sử dụng thực thể bạn vừa tạo mà không có truy vấn bổ sung.

+0

+1 Để khuếch đại: "làm cách nào để đọc ngay sau?" bạn không thể, đó không phải là mục tiêu thiết kế của NDB và có lý do chính đáng là nó không có sẵn ngay lập tức. – msw

+7

Để làm rõ: lý do đó không liên quan gì đến NDB - các ngữ nghĩa truy vấn HRD này được thực hiện trong phần cuối. NDB chỉ đi theo tin xấu. (Tại sao OP lại cố gắng như thế này: các dự đoán của tôi tốt như bất kỳ điều gì, nhưng tôi mong đợi ví dụ này được đơn giản hóa so với mã thực sự nơi điều này xảy ra, và/hoặc họ đang viết một số bài kiểm tra; đã dịch các thành ngữ SQL sang App Engine.) –

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