2014-07-14 16 views
5

Supponiamo Ho una raccolta di documenti definita con MongoEngine come:Mongoengine update_one + upsert vs get_or_create obsoleto

class Project(Document): 
    name = StringField(required=True) 
    client = StringField(required=True) 
    code = StringField(required=True,unique=True) 
    created = DateTimeField(required=True,default=datetime.datetime.now) 

Storicamente, ho potuto usare il metodo get_or_create di eseguire un'operazione di tipo "inserire o aggiornare". Per esempio:

Project.objects().get_or_create(name="Test Project One", 
           client="Client One", 
           code="CL1-001") 

che aggiunge la seguente documento alla raccolta:

{ 
    "name": "Test Project One", 
    "client": "Client One", 
    "code": "CL1-001", 
    "created": { 
     "$date": "2014-07-14T14:00:38.024Z" 
    } 
} 

Ora che questo metodo has been depreciated il recommend alternative è quello di utilizzare update_one con upsert=True come segue:

Project.objects(code="CL1-002").update_one(set__name="Test Project Two", 
              set__client="Client One", 
              upsert=True) 

Ma ciò comporta l'aggiunta di un documento alla raccolta senza il campo created:

{ 
    "client": "Client One", 
    "code": "CL1-002", 
    "name": "Test Project Two" 
} 

è che non c'è alcun modo per replicare il comportamento campo get_or_create default con MongoEngine senza una condizione di competizione?

risposta

8

Questo al momento non è supportato automaticamente, ma potrebbe essere - si prega di aggiungere un biglietto e i manutentori possono rivedere.

Nel frattempo è possibile utilizzare $setOnInsert che imposta un valore solo se si inserisce e che replicherà che cosa è necessario per esempio:

Project.objects(code="CL1-002").update_one(set_on_insert__created=Project().created, 
              set__name="Test Project Two", 
              set__client="Client One", 
              upsert=True)