尝试迭代.all()查询

时间:2017-04-02 06:34:52

标签: python sqlalchemy typeerror

我有一个python BaseHTTPServer,它通过.all()查询返回一个餐馆列表。它在第一次运行时工作正常,但在更新后我得到了

Exception happened during processing of request from ('10.0.2.2', 49927)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
    self.handle()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 340, in handle
    self.handle_one_request()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 328, in handle_one_request
    method()
  File "webserver.py", line 43, in do_GET
    allRestaurants = session.query(Restaurant).all()
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2703, in all
    return list(self)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2855, in __iter__
    return self._execute_and_instances(context)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2876, in _execute_and_instances
    close_with_result=True)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2885, in _get_bind_args
    **kw
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 2867, in _connection_from_session
    conn = self.session.connection(**kw)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 966, in connection
    execution_options=execution_options)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 971, in _connection_for_bind
    engine, execution_options)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 382, in _connection_for_bind
    self._assert_active()
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 276, in _assert_active
    % self._rollback_exception
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/exc.py", line 258, in __str__
    details.append("[parameters: %r]" % params_repr)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/util.py", line 368, in __repr__
    return self._repr_multi(self.params, typ)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/util.py", line 386, in _repr_multi
    for params in multi_params)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/util.py", line 386, in <genexpr>
    for params in multi_params)
  File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/sql/util.py", line 412, in _repr_params
    ", ".join(trunc(value) for value in params)
TypeError: 'int' object is not iterable

.all()查询是否返回i​​nt而不是列表? 或者这是一些内部错误,sqlalchemy的一部分传递另一部分int而不是可迭代的东西? 它超出了我的专业知识来调试库,所以我只是摸不着头脑。 请帮忙。 这是我的网络服务器文件的缩写版本:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import cgi
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database_setup import Base, Restaurant, MenuItem

# Database setup on webserver load instead of pageload
dbpath = 'sqlite:///restaurantmenu.db'
engine = create_engine(dbpath)
Base.metadata.bind = engine
DBSession = sessionmaker(bind = engine)
session = DBSession()
restaurants = session.query(Restaurant)
assert(type(restaurants) != "int")


class webServerHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        try:

            if self.path.endswith("/restaurants"):
                self.send_response(200)
                self.send_header('Content-type', 'text/html')
                self.end_headers()
                output = ""
                output += "<html><body>"
                assert(type(restaurants) != "int"), "type has changed."

                session.flush()
                allRestaurants = session.query(Restaurant).all()
                for restaurant in allRestaurants:
                    output += "<h1>" + restaurant.name + "</h1>"
                    output += '''<a href="http://localhost:8080/restaurants/''' + repr(restaurant.id) + '''/edit">Edit</a>'''
                    output += '''<a href="http://localhost:8080/restaurants/''' + repr(restaurant.id) + '''/delete">Delete</a>'''


                output += "</body></html>"
                self.wfile.write(output)
                print(output)
                return

            if self.path.endswith("/edit"):
                self.send_response(200)
                self.send_header('Content-type', 'text/html')
                self.end_headers()
                id = int(self.path.split('/')[-2])
                restaurant = restaurants.filter_by(id = id).one()
                output = ""
                output += "<html><body>"
                output += "<h1>" + restaurant.name + "</h1>"
                output += '''<form method='POST' enctype='multipart/form-data' action='/restaurants/''' + repr(restaurant.id) + '''/edit'><h2>Please rename the restaurant</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
                output += "</body></html>"
                self.wfile.write(output)
                print(output)
                return       

        except IOError:
            self.send_error(404, 'File Not Found: %s' % self.path)

    def do_POST(self):
        try:
            self.send_response(301)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            ctype, pdict = cgi.parse_header(
                self.headers.getheader('content-type'))
            if ctype == 'multipart/form-data':
                fields = cgi.parse_multipart(self.rfile, pdict)
                formName = self.headers.getheader('name')
                print(fields)
                print(self.path)
                messagecontent = fields.get('message')
                id = int(self.path.split('/')[-2])
                restaurant = restaurants.get(id)
                restaurant.name = messagecontent
                session.add(restaurant)
                session.commit()
                DBSession = sessionmaker(bind = engine)
                session = DBSession()
                assert (restaurants.filter_by(id = id).one().name == messagecontent), "Database update failure"

            output = ""
            output += "<html><body>"
            output += " <h2> Restaurant renamed: </h2>"
            output += "<h1> %s </h1>" % messagecontent[0]
            output += '''<form method='POST' enctype='multipart/form-data' action='/hello'><h2>What would you like me to say?</h2><input name="message" type="text" ><input type="submit" value="Submit"> </form>'''
            output += "</body></html>"
            self.wfile.write(output)
            print(output)
        except:
            pass

UPDATE - 我在数据库提交后添加了DBSession = sessionmaker(bind = engine)和session = DBSession(),现在有了一个InterfaceError:unprintable InterfaceError对象

1 个答案:

答案 0 :(得分:0)

管理解决我遇到的多个问题!

重要的是,不要尝试为网络服务器创建一个会话实例,就像我在do_GETdo_POST方法之外声明会话变量一样。

这是因为文件加载创建了一个会话 - &gt;适用于第一个查询 - &gt;但是,do_POST方法会在commit()调用后使会话无效。这意味着在第二个查询中会话返回一个int(我假设这是一个错误代码形式sqlalchemy),因此是TypeError。

其次,POST方法返回一个表单字段值列表,然后我尝试将其分配给String数据库字段。