2011-01-18 25 views
18

Trong Google App Engine, có một thứ như ListProperty cho phép bạn giữ một danh sách (mảng) các mục. Bạn cũng có thể chỉ định loại mục đang được giữ, ví dụ như chuỗi, số nguyên hoặc bất kỳ thứ gì.Danh sách tài liệu tham khảo trong Google App Engine cho Python

Google App Engine cũng cho phép bạn có ReferenceProperty. ReferenceProperty "chứa" tham chiếu đến một thực thể Mô hình Công cụ Ứng dụng Google khác. Nếu bạn truy cập một ReferenceProperty, nó sẽ tự động truy xuất thực thể thực mà tham chiếu trỏ đến. Điều này là thuận tiện, vì nó nhịp đập nhận được chìa khóa, và sau đó nhận được thực thể cho chính nói.

Tuy nhiên, tôi không thấy bất kỳ điều nào như một ListReferenceProperty (hoặc ReferenceListProperty). Tôi muốn giữ một danh sách các tham chiếu đến các thực thể khác, điều đó sẽ tự động được giải quyết khi tôi cố truy cập các phần tử trong danh sách. Gần nhất tôi có thể nhận được nó có vẻ là để giữ một danh sách các đối tượng db.Key. Tôi có thể sử dụng các phím này để sau đó truy xuất các thực thể liên quan của chúng theo cách thủ công từ máy chủ.

Có giải pháp nào tốt cho điều này không? Về cơ bản, tôi muốn có khả năng có một tập hợp các tham chiếu (tự động dereferencing) cho các thực thể khác. Tôi gần như có thể đạt được điều đó bằng cách có một bộ sưu tập chìa khóa cho các thực thể khác, nhưng tôi muốn nó "biết" rằng đây là những thứ quan trọng, và nó có thể coi trọng chúng như một dịch vụ cho tôi.

Cảm ơn bạn

Trả lời

13

Bước một:

Sử dụng db.ListProperty (db.Key) để tạo ra các mối quan hệ. Bạn muốn ListProp nằm trên Entity sẽ có ít tham chiếu hơn trong mối quan hệ Nhiều đến Nhiều. Điều này cũng sẽ cung cấp cho bạn một tham chiếu trở lại. Vì vậy:

class Spam 
    prop1 = db.String 
    eggs = db.List 

class Eggs 
    prop1 = db.string 
    @property 
    def spams(self): 
    return Spam.all().filter('eggs', self.key()) 

Điều này cung cấp Tham chiếu cả hai cách.

Bước hai:

Tạo một phương pháp vô ích mà thuộc tính không hợp lệ.

def prefetch_refprops(entities, *props): 
    """Dereference Reference Properties to reduce Gets. See: 
    http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine 
    """ 
    fields = [(entity, prop) for entity in entities for prop in props] 
    ref_keys = [prop.get_value_for_datastore(x) for x, prop in fields] 
    ref_entities = dict((x.key(), x) for x in db.get(set(ref_keys))) 
    for (entity, prop), ref_key in zip(fields, ref_keys): 
     prop.__set__(entity, ref_entities[ref_key]) 
    return entities 

Cách sử dụng sẽ là:

derefrenced_spams = prefetch_refprops(Spams, models.Spam.eggs)  
+0

Stephen cậu thử loại này? Tôi sử dụng phương pháp này mọi lúc và ban đầu được đề xuất bởi những người tham gia hangout trên Google App Engine IRC. –

+0

Xin lỗi, tôi sẽ thử ngay khi tôi ra khỏi vòng lặp lặp hiện tại. Cảm ơn bạn đã phản hồi. –

+0

Vâng, nó là một cái gì đó. Ý tôi là, nó sẽ là gọn gàng nếu nó là một tài sản thực sự hiểu rằng đó là một danh sách các tài liệu tham khảo và tất cả, nhưng vẫn còn. Đây là câu trả lời tốt nhất mà tôi đã thấy cho đến nay. –

6

Bạn nói đúng, không có tích hợp ReferenceListProperty. Bạn có thể viết một bản thân - các lớp con thuộc tính tùy chỉnh nói chung khá dễ dàng - nhưng làm cho nó đúng là khó hơn bạn nghĩ, khi nói đến việc trì hoãn và lưu vào bộ nhớ đệm một danh sách các tham chiếu. Tuy nhiên, bạn có thể sử dụng một số db.ListProperty(db.Key), cho phép bạn lưu trữ danh sách các phím. Sau đó, bạn có thể tải chúng riêng lẻ hoặc tất cả cùng một lúc bằng cách sử dụng hoạt động hàng loạt db.get(). Điều này đòi hỏi bạn phải tự mình thực hiện bước phân giải, nhưng nó cũng cho phép bạn kiểm soát nhiều hơn đối với các thực thể dereference.

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