I am using the Peewee library in Python and I want to check if a query exists. I do not want to create a record if it doesn't exist, so I don't want to use get_or_create. There must be a better solution than to use try/except with get but I don't see anything. Please let me know if there is a better way. Thanks.
You can use .exists()
:
query = User.select().where(User.username == 'charlie')
if query.exists():
# A user named "charlie" exists.
cool()
http://docs.peewee-orm.com/en/latest/peewee/api.html?highlight=exists#SelectBase.exists
db.atomic()
to "get or create" multiple related entries as part of a single transaction (i.e. not using the function get_or_create()
for each entry), which in your opinion is better to use - try/except
, or exists()
? –
Agraphia If you just need to check existence use the accepted answer.
If you are going to use the record if it exists you can make use of Model.get_or_none() as this removes the need to use a try/catch and will not create a record if the record doesn't exist.
class User(peewee.Model):
username = peewee.CharField(unique=True)
user = User.get_or_none(username='charlie')
if user is not None:
# found user, do something with it
pass
Alternatively, if you want to check if e.g. some other table refers this record, you can use WHERE EXISTS (subquery)
clause. It is not supported natively by PeeWee, but it can be easily constructed:
subquery = Child.select(Param('1')).where(Child.parent == Parent.id)
parents_with_children = Parent.select().where(
Clause(SQL('EXISTS'), subquery))
It is equivalent to the following SQL:
SELECT * FROM parent
WHERE EXISTS (SELECT 1 FROM child
WHERE child.parent_id = parent.id);
Here I used SELECT 1
for subquery to avoid fetching unneeded information (like child.id
). Not sure if such optimization is actually required.
UPD (Feb 2022)
After more than 5 years of peewee
evolution, it looks like the Clause
class is gone.
The following code may work (I didn't have a chance to test it though):
subquery = Child.select(Param('1')).where(Child.parent == Parent.id)
parents_with_children = Parent.select().where(
NodeList((SQL('EXISTS'), subquery)))
Clause
? I cannot find it in the peewee source code. –
Brasilin Clause
was removed or renamed since then. You may find this useful: github.com/coleifer/peewee/commit/2f0b3 - it is one of the latest commits mentioning Clause
class as obsolete and proposing a replacement. –
Callao Parent.select().where(fn.EXISTS(subquery))
. It seems that Peewee is smart enough that you don't even need the Param('1')
in your subquery. So subquery = Child.select().where(Child.parent == Parent.id)
actually turns into a select 1
when used in the exists for some reason. –
Brasilin © 2022 - 2024 — McMap. All rights reserved.