0

I get a TypeError when I try to get data from MySQL table and assign it to a queryset using following code in Django ModelViewSet

def queryset(self, request):
      conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='password123', db='sakila')
      cur = conn.cursor()
      cur.execute("SELECT  city_id, city, country_id FROM city")
      json.dumps(list(cur))

      cur.close()
      conn.close()

It gives me following error

Exception Value: 'method' object is not iterable

What am I doing wrong? Any solutions? I'm kind of a noob so if you could explain the solution too, that would be great.

Traceback:

  File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\core\handlers\base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view
  58.         return view_func(*args, **kwargs)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\rest_framework\viewsets.py" in view
  87.             return self.dispatch(request, *args, **kwargs)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\rest_framework\views.py" in dispatch
  466.             response = self.handle_exception(exc)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\rest_framework\views.py" in dispatch
  463.             response = handler(request, *args, **kwargs)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\rest_framework\mixins.py" in list
  48.         return Response(serializer.data)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\rest_framework\serializers.py" in data
  674.         ret = super(ListSerializer, self).data

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\rest_framework\serializers.py" in data
  239.                 self._data = self.to_representation(self.instance)

> File "C:\Users\Naila Akbar\AppData\Local\Programs\Python\Python35-32\lib\site-packages\rest_framework\serializers.py" in to_representation
  614.             self.child.to_representation(item) for item in iterable

> Exception Type: TypeError at /cities/

> Exception Value: 'method' object is not iterable
4
  • Please include the full traceback of your exception, because it isn't clear where that error is coming from. Commented Apr 22, 2016 at 7:33
  • @MartijnPieters I don't know how to include traceback but I try.. Commented Apr 22, 2016 at 7:35
  • I don't see where it happens in the code you posted, but since the error is 'method' object is not iterable and you have a method called queryset and a local var called queryset I suspect they are getting mixed up somewhere, but I don't see where. Try changing one of those names and see if it changes anything. Commented Apr 22, 2016 at 7:42
  • @nephlm tried..still same Commented Apr 22, 2016 at 7:44

1 Answer 1

1

If you are using the Django REST framework, then you are expected to produce model instances (database results) or simple Python primitives (built-in types), and it'll take care of serialisation to JSON for you. By abstracting away the serialization, the framework can implement content-negotiation, where the client can pick what format they receive the data in. That could be JSON, but it could also be something else. I suspect that returning a JSON string is going to upset the assumptions the framework makes.

Return your cursor data in a rest_framework.response.Response object instead, do not serialize this yourself:

from rest_framework.response import Response
from contextlib import closing

# ...
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='password123', db='sakila')
with closing(conn), conn as cur:
    with cur:
        cur.execute("SELECT  city_id, city, country_id FROM city")
        return Response(list(cur))

From the Responses section in the API Guide:

REST framework supports HTTP content negotiation by providing a Response class which allows you to return content that can be rendered into multiple content types, depending on the client request.

The Response class subclasses Django's SimpleTemplateResponse. Response objects are initialised with data, which should consist of native Python primitives. REST framework then uses standard HTTP content negotiation to determine how it should render the final response content.

In the above example I also used contextlib.closing() to ensure the connection is closed even if there are exceptions in the view, and then used the connection as a context manager to produce the cursor, and then the cursor to ensure it too is closed.

If you do have an an actual model, then use the Django ORM and don't create direct connections yourself. You are using a big, well-integrated machine and are ignoring 95% of that machine here. You won't get connection pooling, transaction management, pagination, etc. etc. etc. Just use proper querysets and model views in that case.

Sign up to request clarification or add additional context in comments.

11 Comments

I'm doing like this cur.execute("SELECT city_id, city, country_id FROM city") queryset = json.dumps(list(cur))
@NullPointer: yes, that's correct. Please add the full traceback to your question, because if you still get that error then your posted code is not the cause.
@NullPointer: does your function return anything?
@NullPointer: also, I see you are using the Django REST framework to handle this specific function. The framework won't be able to handle already-serialised data like this.
yes I'm working on django rest frame work and using ModelViewSet that returns serialize class and queryset to handle data
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.