2013-08-19 6 views
11

में किसी संपत्ति की विशिष्टता बनाए रखें एक एनडीबी मॉडल में दो गुण होते हैं: email और password। डाटाबेस में दो email के साथ दो रिकॉर्ड जोड़ने से कैसे बचें? एनडीबी के पास संपत्ति के लिए अद्वितीय विकल्प नहीं है, जैसे संबंधपरक डेटाबेस करते हैं।एनडीबी डेटाबेस

जांच की जा रही है कि नए email डेटाबेस में नहीं जोड़ने — मुझे संतुष्ट नहीं करेगा से पहले, क्योंकि दो समानांतर प्रक्रियाओं दोनों एक साथ की जाँच कर सकते हैं और प्रत्येक से एक email जोड़ें।

मुझे यकीन नहीं है कि लेन-देन यहां मदद कर सकते हैं, मैं कुछ मैनुअल पढ़ने के बाद इस छाप के तहत हूं। शायद तुल्यकालिक लेनदेन? क्या इसका मतलब एक समय में है?

उत्तर

6

ईमेल द्वारा इकाई की कुंजी बनाएं, फिर मौजूद होने के लिए get_or_insert का उपयोग करें।

Also read about keys , entities. और models

#ADD 
key_a = ndb.Key(Person, email); 
person = Person(key=key_a) 
person.put() 

#Insert unique  
a = Person.get_or_insert(email) 

या यदि आप बस की जाँच करना चाहते हैं

#ADD 
key_a = ndb.Key(Person, email); 
person = Person(key=key_a) 
person.put() 

#Check if it's added 
new_key_a =ndb.Key(Person, email); 
a = new_key_a.get() 
if a is not None: 
    return 

ख्याल रखना। ईमेल बदलना वाकई मुश्किल होगा (नई प्रविष्टि बनाने और नए प्रविष्टियों को सभी प्रविष्टियों की प्रतिलिपि बनाने की आवश्यकता है)।

उस चीज़ के लिए शायद आपको ईमेल को किसी अन्य इकाई में स्टोर करने की आवश्यकता है और उपयोगकर्ता इसका मूल हो।

लेनदेन का उपयोग करने और ईमेल संपत्ति की जांच करने का एक और तरीका है। रास्ते में लेनदेन का काम: सबसे पहले जो जीतता है वह जीतता है। एक अवधारणा जिसका अर्थ है कि यदि 2 उपयोगकर्ता ईमेल की जांच करते हैं तो केवल पहला (भाग्यशाली) सफल होगा, इस प्रकार आपका डेटा सुसंगत रहेगा।

+0

get_or_insert() का उपयोग करके मुझे यकीन नहीं होगा: या तो मैंने एक नया रिकॉर्ड जोड़ा है या मुझे मौजूदा मिला है। – Graduate

+1

बदलते ईमेल को ** ** या बेहतर में दर्द होगा .. संभव नहीं है :) तो ईमेल के लिए यह एक अच्छा समाधान नहीं है। – Lipis

+0

@ स्नातक हां 'key_a' तय होना चाहिए। –

4

शायद आप webapp2-प्रमाणीकरण मॉड्यूल की तलाश में हैं, जो यह आपके लिए संभाल सकता है। इसे import webapp2_extras.appengine.auth.models जैसे आयात किया जा सकता है। एक पूर्ण उदाहरण के लिए here देखें।

2

मैं भी इस समस्या का सामना किया है, और समाधान के ऊपर मेरी समस्या का समाधान नहीं:

  • बनाने यह एक महत्वपूर्ण मेरे मामले में अस्वीकार्य था (मैं संपत्ति की जरूरत है भविष्य में अस्थिर हो)
  • ईमेल प्रॉपर्टी पर लेनदेन का उपयोग करके AFAIK काम नहीं करता है (आप लेनदेन के अंदर गैर-कुंजी नामों पर प्रश्न नहीं उठा सकते हैं, इसलिए आप यह जांच नहीं सकते कि ई-मेल पहले से मौजूद है या नहीं)।

मैं बिना किसी गुण के एक अलग मॉडल बना रहा, और अद्वितीय नाम (ईमेल पता) कुंजी नाम के रूप में समाप्त हुआ। मुख्य मॉडल में, मैं ईमेल मॉडल का संदर्भ संग्रहीत करता हूं (ईमेल को स्ट्रिंग के रूप में संग्रहीत करने के बजाय)। फिर, मैं एक लेन-देन 'change_email' कर सकता हूं जो कुंजी द्वारा ईमेल को देखकर विशिष्टता की जांच करता है।

0

यह ऐसा कुछ है जो मैं भी साथ आया हूं और मैं @ रेमको के समाधान की भिन्नता पर बस गया हूं। दिए गए ईमेल के साथ मौजूदा इकाई की जांच के साथ मेरा मुख्य मुद्दा ओपे कहा गया एक संभावित दौड़ स्थिति है। मैंने एक अलग मॉडल जोड़ा जो कुंजी के रूप में एक ईमेल पता का उपयोग करता है और एक संपत्ति है जिसमें टोकन होता है। get_or_insert का उपयोग करके, लौटाई गई टोकन को टोकन के पारित किया जा सकता है और यदि वे मेल खाते हैं तो मॉडल डाला गया था।

import os 
from google.appengine.ext import ndb 

class UniqueEmail(ndb.Model): 
    token = ndb.StringProperty() 

class User(ndb.Model): 
    email = ndb.KeyProperty(kind=UniqueEmail, required=True) 
    password = ndb.StringProperty(required=True) 

def create_user(email, password): 
    token = os.urandom(24) 
    unique_email = UniqueEmail.get_or_insert(email, 
              token=token) 

    if token == unique_email.token: 
     # If the tokens match, that means a UniqueEmail entity 
     # was inserted by this process. 
     # Code to create User goes here. 
    # The tokens do not match, therefore the UniqueEmail entity 
    # was retrieved, so the email is already in use. 
    raise ValueError('That user already exists.') 
संबंधित मुद्दे