Added $setOnInsert support for upserts (#308)

Upserts now possible with just query parameters (#309)
This commit is contained in:
Ross Lawley 2013-05-07 11:11:55 +00:00
parent 52c162a478
commit 870ff1d4d9
4 changed files with 28 additions and 5 deletions

View File

@ -4,6 +4,8 @@ Changelog
Changes in 0.8.0 Changes in 0.8.0
================ ================
- Added $setOnInsert support for upserts (#308)
- Upserts now possible with just query parameters (#309)
- Upserting is the only way to ensure docs are saved correctly (#306) - Upserting is the only way to ensure docs are saved correctly (#306)
- Fixed register_delete_rule inheritance issue - Fixed register_delete_rule inheritance issue
- Fix cloning of sliced querysets (#303) - Fix cloning of sliced querysets (#303)

View File

@ -427,7 +427,7 @@ class QuerySet(object):
.. versionadded:: 0.2 .. versionadded:: 0.2
""" """
if not update: if not update and not upsert:
raise OperationError("No update parameters, would remove data") raise OperationError("No update parameters, would remove data")
if not write_concern: if not write_concern:

View File

@ -24,7 +24,8 @@ MATCH_OPERATORS = (COMPARISON_OPERATORS + GEO_OPERATORS +
STRING_OPERATORS + CUSTOM_OPERATORS) STRING_OPERATORS + CUSTOM_OPERATORS)
UPDATE_OPERATORS = ('set', 'unset', 'inc', 'dec', 'pop', 'push', UPDATE_OPERATORS = ('set', 'unset', 'inc', 'dec', 'pop', 'push',
'push_all', 'pull', 'pull_all', 'add_to_set') 'push_all', 'pull', 'pull_all', 'add_to_set',
'set_on_insert')
def query(_doc_cls=None, _field_operation=False, **query): def query(_doc_cls=None, _field_operation=False, **query):
@ -163,7 +164,9 @@ def update(_doc_cls=None, **update):
if value > 0: if value > 0:
value = -value value = -value
elif op == 'add_to_set': elif op == 'add_to_set':
op = op.replace('_to_set', 'ToSet') op = 'addToSet'
elif op == 'set_on_insert':
op = "setOnInsert"
match = None match = None
if parts[-1] in COMPARISON_OPERATORS: if parts[-1] in COMPARISON_OPERATORS:

View File

@ -296,10 +296,10 @@ class QuerySetTest(unittest.TestCase):
author.save(write_concern=write_concern) author.save(write_concern=write_concern)
result = self.Person.objects.update( result = self.Person.objects.update(
set__name='Ross',write_concern={"w": 1}) set__name='Ross', write_concern={"w": 1})
self.assertEqual(result, 1) self.assertEqual(result, 1)
result = self.Person.objects.update( result = self.Person.objects.update(
set__name='Ross',write_concern={"w": 0}) set__name='Ross', write_concern={"w": 0})
self.assertEqual(result, None) self.assertEqual(result, None)
result = self.Person.objects.update_one( result = self.Person.objects.update_one(
@ -536,6 +536,24 @@ class QuerySetTest(unittest.TestCase):
self.assertEqual(club.members['John']['gender'], "F") self.assertEqual(club.members['John']['gender'], "F")
self.assertEqual(club.members['John']['age'], 14) self.assertEqual(club.members['John']['age'], 14)
def test_upsert(self):
self.Person.drop_collection()
self.Person.objects(pk=ObjectId(), name="Bob", age=30).update(upsert=True)
bob = self.Person.objects.first()
self.assertEqual("Bob", bob.name)
self.assertEqual(30, bob.age)
def test_set_on_insert(self):
self.Person.drop_collection()
self.Person.objects(pk=ObjectId()).update(set__name='Bob', set_on_insert__age=30, upsert=True)
bob = self.Person.objects.first()
self.assertEqual("Bob", bob.name)
self.assertEqual(30, bob.age)
def test_get_or_create(self): def test_get_or_create(self):
"""Ensure that ``get_or_create`` returns one result or creates a new """Ensure that ``get_or_create`` returns one result or creates a new
document. document.