Re: Proposal: QuerySet.exists() method

2007-07-15 Thread Tai Lee

I'm also +1 __nonezero__ -1 .exists(). Using .count() already gives us
the required functionality and makes logical sense, the only question
then is how big of a performance gain do we get by using SELECT 1
LIMIT 1.

SELECT 1 FROM [table] LIMIT 1 also feels kinda hackish to me, and I'm
guessing it's likely not supported in all database engines used by
Django and/or is not the most efficient statement in all supported
engines, in which case .exists() would only become a performance
workaround for some engines and either using .count() or simply
having .exists() as an alias to .count() for those engines where
count(*) or count(pk) is most efficient.

I'd rather petition the PostgreSQL developers to optimise count(*) and
suggest Django users implement their own changes or workaround in the
meantime if they're working with large datasets where count(*) is a
serious performance penalty.

I like Malcom's idea of just checking the first value in a queryset to
save a second SQL statement, but I'm not sure it would be appropriate
in all cases. There may be times when people *just* want to check if
records exist, without actually selecting or iterating through
records. In those cases wouldn't it be more efficient to do a
single .count() than selecting all your records and only returning the
first one?


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-14 Thread Honza Král
On 7/14/07, Malcolm Tredinnick <[EMAIL PROTECTED]> wrote:
>
> On Fri, 2007-07-13 at 16:22 -0500, Adrian Holovaty wrote:
> > I'd like to add a QuerySet.exists() method, which would return True or
> > False if the given QuerySet contains at least one record. This would
> > be more efficient than qs.count() or len(qs) because it would perform
> > the following SQL under the hood:
> >
> > SELECT 1 FROM [table] WHERE [where] LIMIT 1;
>
> Due to Oracle inclusion, this has to be
>
> select count(*) from [table] where [...]

How about
SELECT 1 FROM DUAL WHERE EXISTS ( SELECT 1 FROM [table] WHERE [where] );
for oracle?
it is definitely better then requiring Oracle to count all the rows.

>
> and then check that the result is > 0, at least in the Oracle backend
> (no "limit" extension in Oracle). The problem being that count(*) is not
> an optimised operation in PostgreSQL, however, we haven't yet split up
> those cases in a lot of the code (the recent Oracle merge moved a bunch
> of similar things to the count(*) case and I keep meaning to look at
> whether we can move them all to count(id_col), which is faster).
>


-- 
Honza Král
E-Mail: [EMAIL PROTECTED]
ICQ#:   107471613
Phone:  +420 606 678585

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-14 Thread David Larlet

2007/7/14, Gary Wilson <[EMAIL PROTECTED]>:
>
> James Bennett wrote:
> > On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
> >> I'm biased, because I have an immediate need for this in a project,
> >> but this seems general and useful enough for inclusion in QuerySet.
> >
> > Implementing the check in __nonzero__ and having people test by doing
> > 'if some_queryset' or 'if not some_queryset' feels more Pythonic,
> > while implementing it as a specialized 'exists' method feels closer to
> > SQL. Since the Django ORM already leans more toward the Python side
> > than the SQL, I'd say do __nonzero__ and advise boolean checks on
> > QuerySets instead of implementing a method to do the same.
>
> I agree, James.  I'm +1 for __nonzero__ and -1 for .exists()
>

I agree too, if documentation is a problem it can be resolved with a
simple example. So I'm +1 for __nonzero__ and -1 for .exists()

David

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Gary Wilson

James Bennett wrote:
> On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
>> I'm biased, because I have an immediate need for this in a project,
>> but this seems general and useful enough for inclusion in QuerySet.
> 
> Implementing the check in __nonzero__ and having people test by doing
> 'if some_queryset' or 'if not some_queryset' feels more Pythonic,
> while implementing it as a specialized 'exists' method feels closer to
> SQL. Since the Django ORM already leans more toward the Python side
> than the SQL, I'd say do __nonzero__ and advise boolean checks on
> QuerySets instead of implementing a method to do the same.

I agree, James.  I'm +1 for __nonzero__ and -1 for .exists()

Gary

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Leo Soto M.

On 7/13/07, Malcolm Tredinnick <[EMAIL PROTECTED]> wrote:

[...]
> Due to Oracle inclusion, this has to be
>
> select count(*) from [table] where [...]
>
> and then check that the result is > 0, at least in the Oracle backend
> (no "limit" extension in Oracle). The problem being that count(*) is not
> an optimised operation in PostgreSQL, however, we haven't yet split up
> those cases in a lot of the code (the recent Oracle merge moved a bunch
> of similar things to the count(*) case and I keep meaning to look at
> whether we can move them all to count(id_col), which is faster).

Just curious: In which backends is count(id_col) faster than count(*)?.

I'd say that any decent database engine should take both as the same
(as long as a PK exists and no outer joins are performed), but I could
be wrong and would be happy to know why.

-- 
Leo Soto M.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Malcolm Tredinnick

On Fri, 2007-07-13 at 21:56 -0600, Ian Kelly wrote:
> > By the way, for all database backends except SQLite, you can implement
> > all of this sort of stuff (including exists and __len__) fairly fast
> > using cursor.rowcount (the number of rows in the result set).
> > Unfortunately, SQLite always returns -1 for rowcount. I'm building a few
> > of those optimisations into the QuerySet rewrite as a way to cut down on
> > queries.
> 
> cursor.rowcount is also problematic in cx_Oracle.  IIRC, it returns
> the number of rows modified for an INSERT, UPDATE, or DELETE
> statement, but for a SELECT statement it returns the number of rows
> already fetched rather than the total number of rows.

Ah, yes, that sounds familiar.

Regards,
Malcolm

-- 
Remember that you are unique. Just like everyone else. 
http://www.pointy-stick.com/blog/


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Ian Kelly

> By the way, for all database backends except SQLite, you can implement
> all of this sort of stuff (including exists and __len__) fairly fast
> using cursor.rowcount (the number of rows in the result set).
> Unfortunately, SQLite always returns -1 for rowcount. I'm building a few
> of those optimisations into the QuerySet rewrite as a way to cut down on
> queries.

cursor.rowcount is also problematic in cx_Oracle.  IIRC, it returns
the number of rows modified for an INSERT, UPDATE, or DELETE
statement, but for a SELECT statement it returns the number of rows
already fetched rather than the total number of rows.

Ian

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Malcolm Tredinnick

On Fri, 2007-07-13 at 16:22 -0500, Adrian Holovaty wrote:
> I'd like to add a QuerySet.exists() method, which would return True or
> False if the given QuerySet contains at least one record. This would
> be more efficient than qs.count() or len(qs) because it would perform
> the following SQL under the hood:
> 
> SELECT 1 FROM [table] WHERE [where] LIMIT 1;

Due to Oracle inclusion, this has to be

select count(*) from [table] where [...]

and then check that the result is > 0, at least in the Oracle backend
(no "limit" extension in Oracle). The problem being that count(*) is not
an optimised operation in PostgreSQL, however, we haven't yet split up
those cases in a lot of the code (the recent Oracle merge moved a bunch
of similar things to the count(*) case and I keep meaning to look at
whether we can move them all to count(id_col), which is faster).

> I'm biased, because I have an immediate need for this in a project,
> but this seems general and useful enough for inclusion in QuerySet.
> Thoughts?

I'm +0.

__nonzero__ needs a bit more care, though, I think (although we need it
and it's my fault it hasn't been implemented so far; I'm dragging my
feet a bit too much in this area). We can implement __nonzero__ (more
importantly, make bool() make sense) using a single item lookahead cache
internally. So when you call __nonzero__, it pulls back the first item
to check if it exsits and the subsequently iterating over the queryset
will still return that first item before the rest. Net result is that it
doesn't require two SQL queries to do this:

if qs:
# do something with the results of qs

which is pretty easy to walk into in templates.

By the way, for all database backends except SQLite, you can implement
all of this sort of stuff (including exists and __len__) fairly fast
using cursor.rowcount (the number of rows in the result set).
Unfortunately, SQLite always returns -1 for rowcount. I'm building a few
of those optimisations into the QuerySet rewrite as a way to cut down on
queries.

Regards,
Malcolm


-- 
Experience is something you don't get until just after you need it. 
http://www.pointy-stick.com/blog/


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread James Bennett

On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
> I'm biased, because I have an immediate need for this in a project,
> but this seems general and useful enough for inclusion in QuerySet.

Implementing the check in __nonzero__ and having people test by doing
'if some_queryset' or 'if not some_queryset' feels more Pythonic,
while implementing it as a specialized 'exists' method feels closer to
SQL. Since the Django ORM already leans more toward the Python side
than the SQL, I'd say do __nonzero__ and advise boolean checks on
QuerySets instead of implementing a method to do the same.


-- 
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Michael Trier

+1 on both.  I was needing this just the other day.

Michael

On 7/13/07, Brian Harring <[EMAIL PROTECTED]> wrote:
>
> On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
> > On 7/13/07, SmileyChris <[EMAIL PROTECTED]> wrote:
> > > Adrian, I think it's useful enough. But why do you need a .exists() if
> > > we could just use __nonzero__ (like Ivan suggested)?
> >
> > I hadn't thought of that! Yes, we should definitely implement a
> > QuerySet.__nonzero__() method. However, I'd like there to be an
> > explicit method (named either exists() or any() or whatever), because
> > it's easier to say this:
> >
> > To determine whether a QuerySet has at least one record, call its
> > exists() method.
> >
> > ...than this:
> >
> > To determine whether a QuerySet has at least one record, put it in
> > an "if" statement
>
> tell them to do bool(QuerySetInstance) then; its basically what if is
> doing anyways, and any decent python users will recognize the bool as
> being redundant.
>
> > It's convenient to be able to access the result of exists() inline,
> > rather than having to use it in a certain context, such as within an
> > "if" clause.  Sure, if we went with only __nonzero__(), you could call
> > __nonzero__() directly, but accessing the Python double-underscore
> > magic methods is slightly ugly.
>
> And kills kittens (the protocol methods there usually should be
> accessible by the paired builtin ;).
>
> Either way, -1 on exists, +1 on nonzero.
> ~harring
>
> >
>

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Brian Harring

On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
> On 7/13/07, SmileyChris <[EMAIL PROTECTED]> wrote:
> > Adrian, I think it's useful enough. But why do you need a .exists() if
> > we could just use __nonzero__ (like Ivan suggested)?
>
> I hadn't thought of that! Yes, we should definitely implement a
> QuerySet.__nonzero__() method. However, I'd like there to be an
> explicit method (named either exists() or any() or whatever), because
> it's easier to say this:
>
> To determine whether a QuerySet has at least one record, call its
> exists() method.
>
> ...than this:
>
> To determine whether a QuerySet has at least one record, put it in
> an "if" statement

tell them to do bool(QuerySetInstance) then; its basically what if is
doing anyways, and any decent python users will recognize the bool as
being redundant.

> It's convenient to be able to access the result of exists() inline,
> rather than having to use it in a certain context, such as within an
> "if" clause.  Sure, if we went with only __nonzero__(), you could call
> __nonzero__() directly, but accessing the Python double-underscore
> magic methods is slightly ugly.

And kills kittens (the protocol methods there usually should be
accessible by the paired builtin ;).

Either way, -1 on exists, +1 on nonzero.
~harring

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Jacob Kaplan-Moss

On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
> Yes, we should definitely implement a
> QuerySet.__nonzero__() method. However, I'd like there to be an
> explicit method (named either exists() or any() or whatever), because
[snip]

Agreed -- I'm +0 on .exists() and __nonzero__() being an alias.

Jacob

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Adrian Holovaty

On 7/13/07, SmileyChris <[EMAIL PROTECTED]> wrote:
> Adrian, I think it's useful enough. But why do you need a .exists() if
> we could just use __nonzero__ (like Ivan suggested)?

I hadn't thought of that! Yes, we should definitely implement a
QuerySet.__nonzero__() method. However, I'd like there to be an
explicit method (named either exists() or any() or whatever), because
it's easier to say this:

To determine whether a QuerySet has at least one record, call its
exists() method.

...than this:

To determine whether a QuerySet has at least one record, put it in
an "if" statement

It's convenient to be able to access the result of exists() inline,
rather than having to use it in a certain context, such as within an
"if" clause. Sure, if we went with only __nonzero__(), you could call
__nonzero__() directly, but accessing the Python double-underscore
magic methods is slightly ugly. Make sense?

Adrian

-- 
Adrian Holovaty
holovaty.com | djangoproject.com

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread SmileyChris



On Jul 14, 9:55 am, Ivan Sagalaev <[EMAIL PROTECTED]> wrote:
> Adrian Holovaty wrote:
> > I'd like to add a QuerySet.exists() method, which would return True or
> > False if the given QuerySet contains at least one record. This would
> > be more efficient than qs.count() or len(qs) because it would perform
> > the following SQL under the hood:
>
> > SELECT 1 FROM [table] WHERE [where] LIMIT 1;
>
> > I'm biased, because I have an immediate need for this in a project,
> > but this seems general and useful enough for inclusion in QuerySet.
> > Thoughts?
>
> I often want a queryset to behave like a list in this regard:
>
>  if queryset:
>  # not empty, do something
>
> If you implement it as __nonzero__ this will work more efficient than it
> does now calling __len__.

Adrian, I think it's useful enough. But why do you need a .exists() if
we could just use __nonzero__ (like Ivan suggested)?


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Ivan Sagalaev

Adrian Holovaty wrote:
> I'd like to add a QuerySet.exists() method, which would return True or
> False if the given QuerySet contains at least one record. This would
> be more efficient than qs.count() or len(qs) because it would perform
> the following SQL under the hood:
> 
> SELECT 1 FROM [table] WHERE [where] LIMIT 1;
> 
> I'm biased, because I have an immediate need for this in a project,
> but this seems general and useful enough for inclusion in QuerySet.
> Thoughts?

I often want a queryset to behave like a list in this regard:

 if queryset:
 # not empty, do something


If you implement it as __nonzero__ this will work more efficient than it 
does now calling __len__.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Deryck Hodge

On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
>
> I'd like to add a QuerySet.exists() method, which would return True or
> False if the given QuerySet contains at least one record. This would
> be more efficient than qs.count() or len(qs) because it would perform
> the following SQL under the hood:
>
> SELECT 1 FROM [table] WHERE [where] LIMIT 1;
>
> I'm biased, because I have an immediate need for this in a project,
> but this seems general and useful enough for inclusion in QuerySet.
> Thoughts?
>

Just this week I was thinking it would be nice to have something like
this for what I'm working on -- doing a check against what is
potentially either a large result set or an empty one.  +1 from me.

Cheers,
deyck

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Tom Tobin

On 7/13/07, Tom Tobin <[EMAIL PROTECTED]> wrote:
> +0; seems like a reasonable addition.  I wonder of "any" might be a
> better method name (along the lines of the Python 2.5 built-in
> function), but either name would be fine IMHO.

Err, I wonder *if*.  ::sigh::  :-)

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Proposal: QuerySet.exists() method

2007-07-13 Thread Tom Tobin

On 7/13/07, Adrian Holovaty <[EMAIL PROTECTED]> wrote:
>
> I'd like to add a QuerySet.exists() method, which would return True or
> False if the given QuerySet contains at least one record. This would
> be more efficient than qs.count() or len(qs) because it would perform
> the following SQL under the hood:
>
> SELECT 1 FROM [table] WHERE [where] LIMIT 1;

+0; seems like a reasonable addition.  I wonder of "any" might be a
better method name (along the lines of the Python 2.5 built-in
function), but either name would be fine IMHO.

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---