New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove get_or_create #300
Comments
I do not understand how can I easily perform following:
Maybe docs could provide more education and helpful in this. I do this in almost every app I make, because there are always some synchronizations, where I get some data identical as in previous cron job and some are new. I get them usually as already filled model instances from scrapers or data importers. I really do not see a nice way how to deal with this right now. |
I wrote and use something like this in my models: def sync(self):
"""Insert or update, depending on unique fields."""
cls = self.__class__ # model class
# prepare data as in save
self.clean()
# get all unique fields
unique_fields = {}
for key in self._data.keys():
field = getattr(cls, key) # field object
if field.unique:
unique_fields[key] = getattr(self, key) # value
for key in (field.unique_with or []):
unique_fields[key] = getattr(self, key) # value
# select the object by its unique fields
query = cls.objects(**unique_fields)
# prepare data to set
data = {}
for key, value in self._data.items():
data['set__' + key] = value
del data['set__id']
# perform upsert
query.update_one(upsert=True, **data) Not perfect, but close to what I really tend to need in my applications. Maybe I am missing something, but I can't find any nice alternative to this provided directly by MongoEngine. |
Your code seems fine. My workaround approach is quite different though:
My code is lengthy and far from optimal (not friendly to the database). I have duplicated it in most documents because I wasn't aware about Your code seems to be a very nice addition to a common mixin to any document class. The finding of unique fields part could easily be cached in a class attribute, or even determined once and for all in a subclassed regards, |
I agree that it is not easy. Another argument for something else than upsert is that update with upsert doesn't seem to handle properly the fields that have a different 'db_field'. At least, I can't use it, whereas the save method works... |
Merged and removed |
Wait that makes our queryset incompatible with Django's queryset. |
I don't know what "compatible with Django's queryset" really means. We have a couple other things which are different, like "scalar"/"list_values". It was depreciated since a quite long time (2 years) and the problem is that it is simply a lie. With mongo, you just can't have a get_or_create method, as you can never be completely sure, except if you add retry and work with special write_concern settings, that the object you create with such a method wouldn't be created a second time if the same function is called simultaneously from another point. It is just inheritent to the DB type |
I mean that MongoEngine's queryset should be, if possible compatible with Django's queryset because that makes integration with the rest of the Django echosystem just work without much effort on our part. |
mongoengine has deprecated/removed the get_or_create function (MongoEngine/mongoengine#300) So this should fix it
Its bad and has been marked to be removed.
The text was updated successfully, but these errors were encountered: