Maintain uniqueness of a property in the NDB database

后端 未结 5 2070
太阳男子
太阳男子 2020-12-16 00:56

An NDB model contains two properties: email and password. How to avoid adding to the database two records with the same email? NDB doe

5条回答
  •  太阳男子
    2020-12-16 01:27

    This is something that I've come across as well and I settled on a variation of @Remko's solution. My main issue with checking for an existing entity with the given email is a potential race condition like op stated. I added a separate model that uses an email address as the key and has a property that holds a token. By using get_or_insert, the returned entities token can be checked against the token passed in and if they match then the model was inserted.

    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.')
    

提交回复
热议问题