between .one() and .first()

39 views
Skip to first unread message

Chris Withers

unread,
Jun 17, 2013, 2:58:03 AM6/17/13
to sqlal...@googlegroups.com
Hi All,

I seems to commonly need to do a query which should return zero or one
mapped objects.

.one() isn't what I want as no returned object is ok.

.first() isn't what I want as if my query would return more than one
object, I have the query wrong and so want an exception.

Is there something already available that meets this need?

cheers,

Chris

--
Simplistix - Content Management, Batch Processing & Python Consulting
- http://www.simplistix.co.uk

Wichert Akkerman

unread,
Jun 17, 2013, 5:33:43 AM6/17/13
to sqlal...@googlegroups.com

On Jun 17, 2013, at 08:58 , Chris Withers <ch...@simplistix.co.uk> wrote:

> Hi All,
>
> I seems to commonly need to do a query which should return zero or one mapped objects.
>
> .one() isn't what I want as no returned object is ok.
>
> .first() isn't what I want as if my query would return more than one object, I have the query wrong and so want an exception.
>
> Is there something already available that meets this need?

This will requrie you to run a query which limits the result to max 2 rows so you can check if more than one result would be returned. I would just create a simple wrapper function:


def one_optional(query):
rows = query.limit(2).all()
count = len(rows)
if count == 0:
return None
elif count == 1:
return rows[0]
else:
raise RuntimeError('More than one result found.')


Wichert.

Michael Bayer

unread,
Jun 17, 2013, 12:36:16 PM6/17/13
to sqlal...@googlegroups.com
you could even drop the limit(2) so that the query renders more simply if eagerloads are present.

Charlie Clark

unread,
Jun 17, 2013, 1:47:56 PM6/17/13
to sqlal...@googlegroups.com
Am 17.06.2013, 08:58 Uhr, schrieb Chris Withers <ch...@simplistix.co.uk>:

> Hi All,
> I seems to commonly need to do a query which should return zero or one
> mapped objects.

> .one() isn't what I want as no returned object is ok.
> .first() isn't what I want as if my query would return more than one
> object, I have the query wrong and so want an exception.

.count() would seem to be your friend here, at least in case that a lot of
rows might be returned.

> Is there something already available that meets this need?

Only if you can express that need as a query.

Charlie
--
Charlie Clark
Managing Director
Clark Consulting & Research
German Office
Kronenstr. 27a
Düsseldorf
D- 40217
Tel: +49-211-600-3657
Mobile: +49-178-782-6226

Petr Viktorin

unread,
Jun 17, 2013, 1:57:26 PM6/17/13
to sqlal...@googlegroups.com
Simply handling NoResultFound should work just fine...

def zero_or_one(query):
try:
return query.one()
except NoResultFound:
return None
> --
> You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+...@googlegroups.com.
> To post to this group, send email to sqlal...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

ian marcinkowski

unread,
Jun 18, 2013, 2:30:04 PM6/18/13
to sqlal...@googlegroups.com
From the docs:
"one()

Return exactly one result or raise an exception.

Raises sqlalchemy.orm.exc.NoResultFound if the query selects no rows.

Raises sqlalchemy.orm.exc.MultipleResultsFound if multiple object
identities are returned, or if multiple rows are returned for a query
that does not return object identities."

Thus, you could:

try:
return query.one()
print ('Yay! One result!')
except NoResultFound:
# Deal with case of zero results
print('Zero results is also good!')
except MultipleResultsFound:
# Deal with case of >1 results
print('This should not happen. :(')
--
Ian Marcinkowski
ianmarc...@gmail.com

Chris Withers

unread,
Jun 21, 2013, 1:40:14 PM6/21/13
to sqlal...@googlegroups.com, Petr Viktorin
Indeed, this just seems like a common need.

Mike, is it common enough to warrant going on the session by default?

cheers,

Chris
Reply all
Reply to author
Forward
0 new messages