Removed get_or_create() method, deprecated since 0.8

This commit is contained in:
Matthieu Rigal 2015-06-12 13:34:28 +02:00
parent 42511aa9cf
commit 7714cca599
5 changed files with 8 additions and 100 deletions

View File

@ -23,6 +23,7 @@ Changes in 0.9.X - DEV
- Document save raise an exception if save_condition fails #1005 - Document save raise an exception if save_condition fails #1005
- Fixes some internal _id handling issue. #961 - Fixes some internal _id handling issue. #961
- Updated URL and Email Field regex validators, added schemes argument to URLField validation. #652 - Updated URL and Email Field regex validators, added schemes argument to URLField validation. #652
- Removed get_or_create() deprecated since 0.8.0. #300
Changes in 0.9.0 Changes in 0.9.0
================ ================

View File

@ -263,21 +263,11 @@ no document matches the query, and
if more than one document matched the query. These exceptions are merged into if more than one document matched the query. These exceptions are merged into
your document definitions eg: `MyDoc.DoesNotExist` your document definitions eg: `MyDoc.DoesNotExist`
A variation of this method exists, A variation of this method, get_or_create() existed, but it was unsafe. It
:meth:`~mongoengine.queryset.QuerySet.get_or_create`, that will create a new could not be made safe, because there are no transactions in mongoDB. Other
document with the query arguments if no documents match the query. An approaches should be investigated, to ensure you don't accidentally duplicate
additional keyword argument, :attr:`defaults` may be provided, which will be data when using something similar to this method. Therefore it was deprecated
used as default values for the new document, in the case that it should need in 0.8 and removed in 0.10.
to be created::
>>> a, created = User.objects.get_or_create(name='User A', defaults={'age': 30})
>>> b, created = User.objects.get_or_create(name='User A', defaults={'age': 40})
>>> a.name == b.name and a.age == b.age
True
.. warning::
:meth:`~mongoengine.queryset.QuerySet.get_or_create` method is deprecated
since :mod:`mongoengine` 0.8.
Default Document queries Default Document queries
======================== ========================

View File

@ -258,54 +258,6 @@ class BaseQuerySet(object):
""" """
return self._document(**kwargs).save() return self._document(**kwargs).save()
def get_or_create(self, write_concern=None, auto_save=True,
*q_objs, **query):
"""Retrieve unique object or create, if it doesn't exist. Returns a
tuple of ``(object, created)``, where ``object`` is the retrieved or
created object and ``created`` is a boolean specifying whether a new
object was created. Raises
:class:`~mongoengine.queryset.MultipleObjectsReturned` or
`DocumentName.MultipleObjectsReturned` if multiple results are found.
A new document will be created if the document doesn't exists; a
dictionary of default values for the new document may be provided as a
keyword argument called :attr:`defaults`.
.. note:: This requires two separate operations and therefore a
race condition exists. Because there are no transactions in
mongoDB other approaches should be investigated, to ensure you
don't accidentally duplicate data when using this method. This is
now scheduled to be removed before 1.0
:param write_concern: optional extra keyword arguments used if we
have to create a new document.
Passes any write_concern onto :meth:`~mongoengine.Document.save`
:param auto_save: if the object is to be saved automatically if
not found.
.. deprecated:: 0.8
.. versionchanged:: 0.6 - added `auto_save`
.. versionadded:: 0.3
"""
msg = ("get_or_create is scheduled to be deprecated. The approach is "
"flawed without transactions. Upserts should be preferred.")
warnings.warn(msg, DeprecationWarning)
defaults = query.get('defaults', {})
if 'defaults' in query:
del query['defaults']
try:
doc = self.get(*q_objs, **query)
return doc, False
except self._document.DoesNotExist:
query.update(defaults)
doc = self._document(**query)
if auto_save:
doc.save(write_concern=write_concern)
return doc, True
def first(self): def first(self):
"""Retrieve the first object matching the query. """Retrieve the first object matching the query.
""" """

View File

@ -2152,9 +2152,7 @@ class FieldTest(unittest.TestCase):
obj = Product.objects(company=None).first() obj = Product.objects(company=None).first()
self.assertEqual(obj, me) self.assertEqual(obj, me)
obj, created = Product.objects.get_or_create(company=None) obj = Product.objects.get(company=None)
self.assertEqual(created, False)
self.assertEqual(obj, me) self.assertEqual(obj, me)
def test_reference_query_conversion(self): def test_reference_query_conversion(self):

View File

@ -340,8 +340,7 @@ class QuerySetTest(unittest.TestCase):
write_concern = {"fsync": True} write_concern = {"fsync": True}
author, created = self.Person.objects.get_or_create( author = self.Person.objects.create(name='Test User')
name='Test User', write_concern=write_concern)
author.save(write_concern=write_concern) author.save(write_concern=write_concern)
result = self.Person.objects.update( result = self.Person.objects.update(
@ -730,38 +729,6 @@ class QuerySetTest(unittest.TestCase):
self.assertEqual(record.embed_no_default.field, 2) self.assertEqual(record.embed_no_default.field, 2)
self.assertEqual(record.embed.field, 2) self.assertEqual(record.embed.field, 2)
def test_get_or_create(self):
"""Ensure that ``get_or_create`` returns one result or creates a new
document.
"""
person1 = self.Person(name="User A", age=20)
person1.save()
person2 = self.Person(name="User B", age=30)
person2.save()
# Retrieve the first person from the database
self.assertRaises(MultipleObjectsReturned,
self.Person.objects.get_or_create)
self.assertRaises(self.Person.MultipleObjectsReturned,
self.Person.objects.get_or_create)
# Use a query to filter the people found to just person2
person, created = self.Person.objects.get_or_create(age=30)
self.assertEqual(person.name, "User B")
self.assertEqual(created, False)
person, created = self.Person.objects.get_or_create(age__lt=30)
self.assertEqual(person.name, "User A")
self.assertEqual(created, False)
# Try retrieving when no objects exists - new doc should be created
kwargs = dict(age=50, defaults={'name': 'User C'})
person, created = self.Person.objects.get_or_create(**kwargs)
self.assertEqual(created, True)
person = self.Person.objects.get(age=50)
self.assertEqual(person.name, "User C")
def test_bulk_insert(self): def test_bulk_insert(self):
"""Ensure that bulk insert works """Ensure that bulk insert works
""" """