pony
pony copied to clipboard
get_or_create method for entities
A method like get_or_create
would be useful to avoid boilerplate code with the following pattern:
@classmethod
def get_or_create(cls, **kwargs):
r = cls.get(**kwargs)
if r is None:
return cls(**kwargs), True
else:
return r, False
See also Django's get_or_create
.
I've just started looking at Pony ORM, and therefore might have likely missed something.
I vote for similar method
@classmethod
def update_or_create(cls, **kwargs):
try:
instance = cls[tuple(
kwargs[pk_attr.name]
for pk_attr in cls._pk_attrs_
)]
except orm.ObjectNotFound:
return cls(**kwargs)
else:
instance.set(**kwargs)
return instance
+1
I use this trick:
from pony.orm.core import EntityMeta
from pony import orm
def upsert(cls, get, set=None):
"""
Interacting with Pony entities.
:param cls: The actual entity class
:param get: Identify the object (e.g. row) with this dictionary
:param set:
:return:
"""
# does the object exist
assert isinstance(cls, EntityMeta), "{cls} is not a database entity".format(cls=cls)
# if no set dictionary has been specified
set = set or {}
if not cls.exists(**get):
# make new object
return cls(**set, **get)
else:
# get the existing object
obj = cls.get(**get)
for key, value in set.items():
obj.__setattr__(key, value)
return obj
Relatedly, having an Entity method like update
would be nice, which would be equivalent to:
def update(**values):
for key, value in values.items():
self.__setattr__(key, value)
There is such method called set.
Oh, so there is! Thanks.
Looks like @tschm's upsert
method can be simplified, in that case.
Has this been implemented yet? This seems like something that would come out of the box
Really need this one
It would be awesome to have this.
I vote for similar method
@classmethod def update_or_create(cls, **kwargs): try: instance = cls[tuple( kwargs[pk_attr.name] for pk_attr in cls._pk_attrs_ )] except orm.ObjectNotFound: return cls(**kwargs) else: instance.set(**kwargs) return instance
This function is perfect! should just be added to pony!
EDIT: I take that back, we should probably create, and catch an IntegrityError, and then update instead to avoid a race condition.