PyMongo 奇怪错误“TypeError:“Database”对象不可调用。”
我遇到了一个奇怪的错误。
来源: __init__.py
import os
import base64
import uuid
import tornado.web
import tornado.httpserver
import tornado.locale
import tornado.ioloop
import tornado.options
from tornado.options import define, options
from pymongo.connection import Connection
from pymongo.database import Database
from handlers import api
#from auth import AuthLoginHandler
#from auth import AuthLogoutHandler
#from auth import AuthFirstRunHandler
from handlers import home
## Options
define("listen_port", default = 7456, type = "int",
help = "bind to port")
define("listen_address", default = None, type = "string",
help = "bind to address")
define("static_path", default = os.path.join(os.path.dirname(__file__), "static"), type = "string",
help = "directory to store static resource")
# http://www.v2ex.com/t/12646
define("cookie_secret", default = base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes), type = "string",
help = "cookie")
define("mongo_host", default = "127.0.0.1", type = "string",
help = "hostname or ip of mongo host")
define("mongo_port", default = 27017, type = "int",
help = "port of mongo host")
define("mongo_collection", default = "meowth", type = "string",
help = "collection name")
tornado.options.parse_command_line()
class Application(tornado.web.Application):
def __init__(self):
tornado.web.Application.__init__(self, [
(r"/i", home.HomeHandler),
# (r"/auth/login", AuthLoginHandler),
# (r"/auth/logout", AuthLogoutHandler),
# (r"/auth/install", AuthFirstRunHandler),
# (r"/backstage", BackstageHomeHandler),
(r"/api/cluster", api.APIHandler),
(r"/api/user", api.APIHandler),
(r"/api/connection", api.APIHandler),
(r"/api/control", api.APIHandler),
(r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : options.static_path })
],** dict(
xsrf_cookies = True,
cookie_secret = options.cookie_secret
))
# init database connection
self.mongo = Database(
Connection(
options.mongo_host,
options.mongo_port
),
options.mongo_collection
)
#self.mongo = self.mongoConnection[options.mongo_collection]
#self.mongo = self.mongoConnection.meowth
def main():
if options.listen_address == None:
tornado.httpserver.HTTPServer(Application()).listen(options.listen_port)
else:
tornado.httpserver.HTTPServer(Application()).listen(options.listen_port, address = options.listen_address)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
base.py
# -*- coding: utf8 -*-
import tornado.web
import pymongo
class BaseHandler(tornado.web.RequestHandler):
def __init__(self, application, request, **kwargs):
tornado.web.RequestHandler.__init__(self, application, request, **kwargs)
self.session_id = self.get_secure_cookie("meowth_session")
self.session = {}
@property
def db(self):
print self.application.mongo
return self.application.mongo
def init_session(self):
if not self.session_id:
self.session_id = self.db().meowth_sessions.save(
{"data" : self.session}
)
else:
self.session = self.db().meowth_sessions.find_one(
{"_id" : self.session_id}
)
def flush_session(self):
self.db().meowth_sessions.save(
{"data" : self.session,
"_id" : self.session_id
}
)
def is_spider(self):
# https://bitbucket.org/keakon/doodle/src/3ddf46ac59e7/zh-CN/common.py#cl-512
user_agent = self.request.headers["User-Agent"]
if 'bot' in user_agent or 'spider' in user_agent:
return True
return False
错误:
> [root@CloudK02 Meowth]# ./Meowth-Web Database(Connection('127.0.0.1',
> 27017), u'meowth') [E 120219 15:07:54 web:1031] Uncaught exception GET
> /i (122.94.31.186)
> HTTPRequest(protocol='http', host='us1.loli.vg:7456', method='GET', uri='/i', version='HTTP/1.1', remote_ip='122.94.31.186',
> body='', headers={'Accept-Language': 'en-US,en;q=0.8',
> 'Accept-Encoding': 'gzip,deflate,sdch', 'Host': 'us1.loli.vg:7456',
> 'Accept':
> 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
> 'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML,
> like Gecko) Chrome/17.0.963.56 Safari/535.11', 'Accept-Charset':
> 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Connection': 'keep-alive',
> 'Cookie': 'PHPSESSID=rm4ght6ivop9a1hf5oogcft3j4;
> session_id="MzZkODNiMWMyZjczOWZhNzcxYjU4YTNjNzVhZjA4Yzc=|1329674350|2562f7ed871c1ca3e24dcb5891d6e753cfacfa44";
> rock_format=json', 'Cache-Control': 'max-age=0'})
> Traceback (most recent call last):
> File "/usr/local/lib/python2.6/site-packages/tornado/web.py", line 988, in _execute
> getattr(self, self.request.method.lower())(*args, **kwargs)
> File "/home/aveline/Meowth/web/handlers/home.py", line 7, in get
> self.init_session()
> File "/home/aveline/Meowth/web/handlers/base.py", line 19, in init_session
> self.session_id = self.db().meowth_sessions.save(
> File "build/bdist.linux-x86_64/egg/pymongo/database.py", line 696, in __call__
> "failing because no such method exists." % self.__name)
> TypeError: 'Database' object is not callable. If you meant to call the 'meowth' method on a 'Connection' object it is failing because no
> such method exists.
如果我在 Application 类中使用 self.mongo,效果很好。 但是如果我在 BaseHandler 类中使用它,就会出现错误。
为什么?
I got a strange error.
Source:__init__.py
import os
import base64
import uuid
import tornado.web
import tornado.httpserver
import tornado.locale
import tornado.ioloop
import tornado.options
from tornado.options import define, options
from pymongo.connection import Connection
from pymongo.database import Database
from handlers import api
#from auth import AuthLoginHandler
#from auth import AuthLogoutHandler
#from auth import AuthFirstRunHandler
from handlers import home
## Options
define("listen_port", default = 7456, type = "int",
help = "bind to port")
define("listen_address", default = None, type = "string",
help = "bind to address")
define("static_path", default = os.path.join(os.path.dirname(__file__), "static"), type = "string",
help = "directory to store static resource")
# http://www.v2ex.com/t/12646
define("cookie_secret", default = base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes), type = "string",
help = "cookie")
define("mongo_host", default = "127.0.0.1", type = "string",
help = "hostname or ip of mongo host")
define("mongo_port", default = 27017, type = "int",
help = "port of mongo host")
define("mongo_collection", default = "meowth", type = "string",
help = "collection name")
tornado.options.parse_command_line()
class Application(tornado.web.Application):
def __init__(self):
tornado.web.Application.__init__(self, [
(r"/i", home.HomeHandler),
# (r"/auth/login", AuthLoginHandler),
# (r"/auth/logout", AuthLogoutHandler),
# (r"/auth/install", AuthFirstRunHandler),
# (r"/backstage", BackstageHomeHandler),
(r"/api/cluster", api.APIHandler),
(r"/api/user", api.APIHandler),
(r"/api/connection", api.APIHandler),
(r"/api/control", api.APIHandler),
(r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : options.static_path })
],** dict(
xsrf_cookies = True,
cookie_secret = options.cookie_secret
))
# init database connection
self.mongo = Database(
Connection(
options.mongo_host,
options.mongo_port
),
options.mongo_collection
)
#self.mongo = self.mongoConnection[options.mongo_collection]
#self.mongo = self.mongoConnection.meowth
def main():
if options.listen_address == None:
tornado.httpserver.HTTPServer(Application()).listen(options.listen_port)
else:
tornado.httpserver.HTTPServer(Application()).listen(options.listen_port, address = options.listen_address)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
base.py
# -*- coding: utf8 -*-
import tornado.web
import pymongo
class BaseHandler(tornado.web.RequestHandler):
def __init__(self, application, request, **kwargs):
tornado.web.RequestHandler.__init__(self, application, request, **kwargs)
self.session_id = self.get_secure_cookie("meowth_session")
self.session = {}
@property
def db(self):
print self.application.mongo
return self.application.mongo
def init_session(self):
if not self.session_id:
self.session_id = self.db().meowth_sessions.save(
{"data" : self.session}
)
else:
self.session = self.db().meowth_sessions.find_one(
{"_id" : self.session_id}
)
def flush_session(self):
self.db().meowth_sessions.save(
{"data" : self.session,
"_id" : self.session_id
}
)
def is_spider(self):
# https://bitbucket.org/keakon/doodle/src/3ddf46ac59e7/zh-CN/common.py#cl-512
user_agent = self.request.headers["User-Agent"]
if 'bot' in user_agent or 'spider' in user_agent:
return True
return False
Error:
> [root@CloudK02 Meowth]# ./Meowth-Web Database(Connection('127.0.0.1',
> 27017), u'meowth') [E 120219 15:07:54 web:1031] Uncaught exception GET
> /i (122.94.31.186)
> HTTPRequest(protocol='http', host='us1.loli.vg:7456', method='GET', uri='/i', version='HTTP/1.1', remote_ip='122.94.31.186',
> body='', headers={'Accept-Language': 'en-US,en;q=0.8',
> 'Accept-Encoding': 'gzip,deflate,sdch', 'Host': 'us1.loli.vg:7456',
> 'Accept':
> 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
> 'User-Agent': 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML,
> like Gecko) Chrome/17.0.963.56 Safari/535.11', 'Accept-Charset':
> 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Connection': 'keep-alive',
> 'Cookie': 'PHPSESSID=rm4ght6ivop9a1hf5oogcft3j4;
> session_id="MzZkODNiMWMyZjczOWZhNzcxYjU4YTNjNzVhZjA4Yzc=|1329674350|2562f7ed871c1ca3e24dcb5891d6e753cfacfa44";
> rock_format=json', 'Cache-Control': 'max-age=0'})
> Traceback (most recent call last):
> File "/usr/local/lib/python2.6/site-packages/tornado/web.py", line 988, in _execute
> getattr(self, self.request.method.lower())(*args, **kwargs)
> File "/home/aveline/Meowth/web/handlers/home.py", line 7, in get
> self.init_session()
> File "/home/aveline/Meowth/web/handlers/base.py", line 19, in init_session
> self.session_id = self.db().meowth_sessions.save(
> File "build/bdist.linux-x86_64/egg/pymongo/database.py", line 696, in __call__
> "failing because no such method exists." % self.__name)
> TypeError: 'Database' object is not callable. If you meant to call the 'meowth' method on a 'Connection' object it is failing because no
> such method exists.
It works well if I use self.mongo in class Application.
But I got an error if I use it in class BaseHandler.
Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您已将
db
定义为属性,这意味着您不必调用它。但后来你就打电话了!删除
@property
或使用self.db
而不是self.db()
。与往常一样,Python 的错误消息提供了丰富的信息,您应该查看它们!在这种情况下,您可以看到
这意味着您正在某处调用(即像函数一样)数据库对象。在哪里?
看?
self.db
是一个属性,因此为您提供self.application.mongo
。然后你调用它,所以上面这行相当于这显然是错误的。
You've defined
db
as a property, meaning that you don't have to call it. But then you call it!Either remove the
@property
or useself.db
instead ofself.db()
.As always, Python's error messages are informative and you should look at them! In this case, you can see
which means that you are calling (i.e. like a function) a database object somewhere. Where?
See?
self.db
is a property, so gives youself.application.mongo
. Then you call it, so the above line is equivalent towhich is obviously wrong.