Create or get

Peewee has one helper method for performing “get/create” type operations:Model.get_or_create(), which first attempts to retrieve the matchingrow. Failing that, a new row will be created.

For “create or get” type logic, typically one would rely on a unique_constraint or primary key to prevent the creation of duplicate objects. As anexample, let’s say we wish to implement registering a new user account usingthe example User model. The _User model has a _unique_constraint on the username field, so we will rely on the database’s integrityguarantees to ensure we don’t end up with duplicate usernames:

  1. try:
  2. with db.atomic():
  3. return User.create(username=username)
  4. except peewee.IntegrityError:
  5. # `username` is a unique column, so this username already exists,
  6. # making it safe to call .get().
  7. return User.get(User.username == username)

You can easily encapsulate this type of logic as a classmethod on your ownModel classes.

The above example first attempts at creation, then falls back to retrieval,relying on the database to enforce a unique constraint. If you prefer toattempt to retrieve the record first, you can useget_or_create(). This method is implemented along the samelines as the Django function of the same name. You can use the Django-stylekeyword argument filters to specify your WHERE conditions. The functionreturns a 2-tuple containing the instance and a boolean value indicating if theobject was created.

Here is how you might implement user account creation usingget_or_create():

  1. user, created = User.get_or_create(username=username)

Suppose we have a different model Person and would like to get or create aperson object. The only conditions we care about when retrieving the Personare their first and last names, but if we end up needing to create a newrecord, we will also specify their date-of-birth and favorite color:

  1. person, created = Person.get_or_create(
  2. first_name=first_name,
  3. last_name=last_name,
  4. defaults={'dob': dob, 'favorite_color': 'green'})

Any keyword argument passed to get_or_create() will be used inthe get() portion of the logic, except for the defaults dictionary,which will be used to populate values on newly-created instances.

For more details read the documentation for Model.get_or_create().