cursor.execute returns LONG

65 views
Skip to first unread message

rikl...@gmail.com

unread,
Oct 29, 2007, 6:47:03 PM10/29/07
to Django users
So I have a function in views:
#################################
def getEntries(user):
"""Returns unique entries and page views for each of last 30 day
"""
cursor = connection.cursor()
query = cursor.execute('SELECT COUNT(DISTINCT(ip)) AS uniqs,
COUNT(ip) AS views, date FROM pw_logs GROUP BY date LIMIT 30')
return query.fetchall()
#################################
The query in phpMyAdmin returns the correct data. In Django-SVN
cursor.execute returns LONG - a number. I used SQLite yesterday with
simillar query (and others) and it worked. Now what I se on MySQL all
or almost all my cursor.execute give LONGs. What's going on?

Jeremy Dunck

unread,
Oct 29, 2007, 7:12:10 PM10/29/07
to django...@googlegroups.com

What's "connection"? Is it django.db.connection?

What're your settings? DATABASE_* and DEBUG are relevant here.

rikl...@gmail.com

unread,
Oct 29, 2007, 8:32:20 PM10/29/07
to Django users

> What's "connection"? Is it django.db.connection?
from django.db import connection
Yes

> What're your settings? DATABASE_* and DEBUG are relevant here.

DEBUG = True
TEMPLATE_DEBUG = DEBUG

DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql',
'mysql', 'sqlite3' or 'ado_mssql'.
DATABASE_NAME = 'test' # Or path to database file if using
sqlite3.
DATABASE_USER = 'root' # Not used with sqlite3.
DATABASE_PASSWORD = '' # Not used with sqlite3.
DATABASE_HOST = 'localhost' # Set to empty string for
localhost. Not used with sqlite3.
DATABASE_PORT = '' # Set to empty string for default. Not
used with sqlite3.

It works for the ORM :)

Malcolm Tredinnick

unread,
Oct 29, 2007, 9:11:17 PM10/29/07
to django...@googlegroups.com

I'm not quite sure what you're saying here. Are you saying it returns
the string "LONG", or that it returns something that has Python type
'long' -- such as 1L, rather than 1? In the latter case, there's no
problem at all here. A long is just a number. Just use it as you
normally would. MySQL always returns longs (for historical reasons, due
to the need for explicit conversions between Python ints and longs in
older Python versions).

Regards,
Malcolm

--
Works better when plugged in.
http://www.pointy-stick.com/blog/

rikl...@gmail.com

unread,
Oct 30, 2007, 1:35:52 PM10/30/07
to Django users
it returns a number type LONG but it schould not. 1. fetchall() and
fetchrow() should do that 2. the query returns (in phpmyadmin) correct
data which is few rows not a simgle number.

Karen Tracey

unread,
Oct 30, 2007, 2:18:01 PM10/30/07
to django...@googlegroups.com
On 10/29/07, rikl...@gmail.com <rikl...@gmail.com> wrote:

So I have a function in views:
#################################
def getEntries(user):
  """Returns unique entries and page views for each of last 30 day
  """
  cursor = connection.cursor ()
  query = cursor.execute('SELECT COUNT(DISTINCT(ip)) AS uniqs,
COUNT(ip) AS views, date FROM pw_logs GROUP BY date LIMIT 30')
  return query.fetchall()
#################################

I believe your code here is relying on undefined behavior, specifically the return value of cursor.execute.  In describing the .execute under the description of cursor objects, the Python Database API Specification v2.0 (http://www.python.org/dev/peps/pep-0249/) states:
Return values are not defined.
So it is permissible for one db backend (sqlite?) to return something on which you can then call fetchall() and another (mysqldb) to return a long.  In mysqldb's case I believe it is returning the number of rows resulting from the query.

If you want to write code that will work for all backends, you must limit your code to behavior that is defined in the spec.  In this specific case it means you should call fetchall on the cursor object, not the return value of execute.

Karen

rikl...@gmail.com

unread,
Oct 30, 2007, 3:15:16 PM10/30/07
to Django users
> If you want to write code that will work for all backends, you must limit
> your code to behavior that is defined in the spec. In this specific case it
> means you should call fetchall on the cursor object, not the return value of
> execute.


thanks, that did the job :)

Malcolm Tredinnick

unread,
Oct 30, 2007, 10:20:17 PM10/30/07
to django...@googlegroups.com
On Tue, 2007-10-30 at 17:35 +0000, rikl...@gmail.com wrote:
> it returns a number type LONG but it schould not.

Why not? You haven't explained why this is an error. If you think the
type is a problem, you're mistaken: a long is just a number. If you
think the fact that it's returning a number is wrong, that's also a bad
assumption: PEP 249 says that execute() can return whatever it likes.

Karen has pointed out a workaround, but there really isn't any bug here.

Regards,
Malcolm

--
How many of you believe in telekinesis? Raise my hand...
http://www.pointy-stick.com/blog/

Reply all
Reply to author
Forward
0 new messages