NDB模型包含兩個屬性:email
和password
。如何避免向數據庫中添加兩條具有相同記錄的記錄email
?與關係數據庫一樣,NDB沒有屬性的UNIQUE選項。維護NDB數據庫中的特性的唯一性
檢查新email
是不是在數據庫中添加—不會滿足我面前,因爲有兩個平行的過程既可以同時做檢查和每添加相同email
。
我不確定交易是否可以在這裏幫助,在閱讀了一些手冊之後,我在這個印象之下。也許同步交易?這是否意味着一次一個?
NDB模型包含兩個屬性:email
和password
。如何避免向數據庫中添加兩條具有相同記錄的記錄email
?與關係數據庫一樣,NDB沒有屬性的UNIQUE選項。維護NDB數據庫中的特性的唯一性
檢查新email
是不是在數據庫中添加—不會滿足我面前,因爲有兩個平行的過程既可以同時做檢查和每添加相同email
。
我不確定交易是否可以在這裏幫助,在閱讀了一些手冊之後,我在這個印象之下。也許同步交易?這是否意味着一次一個?
通過電子郵件創建實體的密鑰,然後使用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個用戶檢查電子郵件只有第一個(幸運)將成功,因此您的數據將是一致的。
也許你正在尋找webapp2-authentication模塊,它可以爲你處理。它可以像這樣導入import webapp2_extras.appengine.auth.models
。查看here的完整示例。
我也遇到了這個問題,上述解決方案並沒有解決我的問題:
我最終創建了一個不帶屬性的單獨模型,並將唯一屬性(電子郵件地址)作爲鍵名稱。在主模型中,我存儲對電子郵件模型的引用(而不是將電子郵件存儲爲字符串)。然後,我可以通過按鍵查找電子郵件來查看「change_email」事務,以檢查唯一性。
這是我遇到的情況,我決定使用@ Remko的解決方案。使用給定的電子郵件檢查現有實體的主要問題是潛在的競爭條件,如op所述。我添加了一個單獨的模型,它使用電子郵件地址作爲密鑰並具有一個包含令牌的屬性。通過使用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.')
使用get_or_insert()我不會肯定的:無論是我添加一個新的記錄或我已經得到了現有的。 – Graduate
改變電子郵件將是痛苦的** ...或更好..不可能:)所以對於電子郵件它不是一個好的解決方案。 – Lipis
@研究生是應該''key_a'固定的。 –