How to make an external database query iterable?

匿名 (未验证) 提交于 2019-12-03 00:52:01

问题:

I have the following code:

settings.py

DATABASES = {     'default': {         'ENGINE': 'django.db.backends.mysql',          'NAME': 'tectcom',                              'USER': 'test',                             'PASSWORD': '***146***',                          'HOST': '',                              'PORT': '',                           },      'cdr': {         'ENGINE': 'django.db.backends.mysql',         'NAME': 'ast',                              'USER': '123',                               'PASSWORD': '654',                          'HOST': '',                               'PORT': '',                          } 

views.py

def cdr_user(request):         cursor = connections['cdr'].cursor()         calls = cursor.execute('SELECT * FROM cdr')         return render_to_response("cdr_user.html",                 {'result':calls }, context_instance=RequestContext(request)) 

cdr_user.html

{% for res in result %}  {{ res.billsec }}<br />  {% endfor %} 

The table is like that:

+-------------+--------------+------+-----+---------------------+-------+ | Field       | Type         | Null | Key | Default             | Extra | +-------------+--------------+------+-----+---------------------+-------+ | calldate    | datetime     | NO   | MUL | 0000-00-00 00:00:00 |       |  | clid        | varchar(80)  | NO   |     |                     |       |  | src         | varchar(80)  | NO   |     |                     |       |  | dst         | varchar(80)  | NO   | MUL |                     |       |  | dcontext    | varchar(80)  | NO   |     |                     |       |  | channel     | varchar(80)  | NO   |     |                     |       |  | dstchannel  | varchar(80)  | NO   |     |                     |       |  | lastapp     | varchar(80)  | NO   |     |                     |       |  | lastdata    | varchar(80)  | NO   |     |                     |       |  | duration    | int(11)      | NO   |     | 0                   |       |  | billsec     | int(11)      | NO   |     | 0                   |       |  | disposition | varchar(45)  | NO   |     |                     |       |  | amaflags    | int(11)      | NO   |     | 0                   |       |  | accountcode | varchar(20)  | NO   | MUL |                     |       |  | userfield   | varchar(255) | NO   |     |                     |       |  | uniqueid    | varchar(32)  | NO   |     |                     |       |  | linkedid    | varchar(32)  | NO   |     |                     |       |  | sequence    | varchar(32)  | NO   |     |                     |       |  | peeraccount | varchar(32)  | NO   |     |                     |       |  +-------------+--------------+------+-----+---------------------+-------+ 

The problem is that I get a "Exception Value: 'long' object is not iterable"

How do I make result iterable to show it in my template? I've seen https://docs.djangoproject.com/en/dev/topics/db/sql/ and also other documentation, but I'm still lost in the code.

Thank you.

回答1:

To iterate over the result of a SQL query in Python, use cursor.fetchall() to turn it into a list of lists. There's a very handy recipe here for turning those results into an object you can easily access:

class SQLRow(object):     def __init__(self, cursor, row):         for (attr, val) in zip((d[0] for d in cursor.description), row) :             setattr(self, attr, val) 

Once you have that class, this is simple:

def cdr_user(request):     cursor = connections['cdr'].cursor()     calls = cursor.execute('SELECT * FROM cdr')     result = [SQLRow(cursor, r) for r in cursor.fetchall()]     return render_to_response("cdr_user.html",             {'result': result }, context_instance=RequestContext(request)) 

This way, the billsec attribute (and all other attributes) will still be accessible in your template.



回答2:

cursor.execute() doesn't return an iterable. It modifies the cursor object in place. Here's some documentation on this.

You need to call .fetchone() .fetchmany() or .fetchall() to retrieve the results, which should be iterables, e.g.:

def cdr_user(request):   cursor = connections['cdr'].cursor()   cursor.execute('SELECT * FROM cdr')   calls = cursor.fetchall()   return render_to_response("cdr_user.html",                             {'result':calls },                              context_instance=RequestContext(request)) 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!