I want to get an object from the database if it already exists (based on provided parameters) or create it if it does not.
Django’s get_or_create (or source) does this. Is there an equivalent shortcut in SQLAlchemy?
I’m currently writing it out explicitly like this:
def get_or_create_instrument(session, serial_number):
instrument = session.query(Instrument).filter_by(serial_number=serial_number).first()
if instrument:
return instrument
else:
instrument = Instrument(serial_number)
session.add(instrument)
return instrument
That’s basically the way to do it, there is no shortcut readily available AFAIK.
You could generalize it ofcourse:
2020 update (Python 3.9+ ONLY)
Here is a cleaner version with Python 3.9’s the new dict union operator (|=)
Note:
Similar to the Django version this will catch duplicate key constraints and similar errors. If your get or create is not guaranteed to return a single result it can still result in race conditions.
To alleviate some of that issue you would need to add another
one_or_none()style fetch right after thesession.commit(). This still is no 100% guarantee against race conditions unless you also use awith_for_update()or serializable transaction mode.