启动app.py,然后终止数据库并点击/api/foo
给我:
peewee.OperationalError:无法连接到服务器:拒绝连接
重新启动数据库可以让我点击/api/foo
给我:
peewee.OperationalError:由于管理员而终止连接 命令\ nSSL连接意外关闭\ n
再次点击/api/foo
会给我:
peewee.InterfaceError:连接已关闭
test_case/__init__.py
#!/usr/bin/env python
from os import environ
from bottle import Bottle, request, response
from playhouse.db_url import connect
bottle_api = Bottle()
db = connect(environ['RDBMS_URI'])
from test_case.foo.models import Foo
db.connect() # Not needed, but do want to throw errors ASAP
db.create_tables([Foo], safe=True) # Create tables (if they don't exist)
from test_case.foo.routes import foo_api
bottle_api.merge(foo_api)
bottle_api.catchall = False
@bottle_api.hook('before_request')
def _connect_db():
print 'Connecting to db'
db.connect()
@bottle_api.hook('after_request')
def _close_db():
print 'Closing db'
if not db.is_closed():
db.close()
def error_catcher(environment, start_response):
try:
return bottle_api.wsgi(environment, start_response)
except Exception as e:
environment['PATH_INFO'] = '/api/error'
environment['api_error'] = e
return bottle_api.wsgi(environment, start_response)
@bottle_api.route('/api/error')
def global_error():
response.status = 500
return {'error': (lambda res: res[res.find("'") + 1:res.rfind("'")])(
str(request.environ['api_error'].__class__)),
'error_message': request.environ['api_error'].message}
test_case/__main__.py
from __init__ import bottle_api
# Or `from __init__ import bottle_api`; `from bottle import run`;
# Then `run(error_catcher, port=5555)`
bottle_api.run(port=5555)
test_case/foo/__init__.py
test_case/foo/models.py
from peewee import Model, CharField
from test_case import db
class Foo(Model):
id = CharField(primary_key=True)
class Meta(object):
database = db
test_case/foo/routes.py
from bottle import Bottle
from playhouse.shortcuts import model_to_dict
from test_case.foo.models import Foo
foo_api = Bottle()
@foo_api.get('/api/foo')
def retrieve_foos():
return {'foos': tuple(model_to_dict(foo) for foo in Foo.select())}
答案 0 :(得分:0)
更新
我认为问题在于如何构建导入以及python如何在sys.path中加载和缓存模块。
我认为你的一个模块正在导入和加载两次,代码库的不同部分使用不同的模块实例。
因此,foo.routes中的视图正在使用数据库对象的一个实例,而连接挂钩正在使用另一个实例。
而不是from __init__
,尝试from test_case import bottle_api
怎么样?这是一个重要的导入声明,可能是我的罪魁祸首。
我在代码中添加了以下内容,以便我可以从命令行运行它:
if __name__ == '__main__':
api.run()
然后我向/api/foo
提出了请求并查看了一些虚假数据。我停止了Postgresql服务器并得到了这个错误:
Traceback (most recent call last):
File "/usr/lib64/python2.7/wsgiref/handlers.py", line 85, in run
self.result = application(self.environ, self.start_response)
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 979, in __call__
return self.wsgi(environ, start_response)
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 954, in wsgi
out = self._cast(self._handle(environ))
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 857, in _handle
self.trigger_hook('before_request')
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/bottle.py", line 640, in trigger_hook
return [hook(*args, **kwargs) for hook in self._hooks[__name][:]]
File "bt.py", line 31, in _connect_db
db.connect()
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 2967, in connect
self.initialize_connection(self.__local.conn)
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 2885, in __exit__
reraise(new_type, new_type(*exc_value.args), traceback)
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 2965, in connect
**self.connect_kwargs)
File "/home/charles/tmp/scrap/bottlez/src/peewee/peewee.py", line 3279, in _connect
conn = psycopg2.connect(database=database, **kwargs)
File "/home/charles/tmp/scrap/bottlez/lib/python2.7/site-packages/psycopg2/__init__.py", line 164, in connect
conn = _connect(dsn, connection_factory=connection_factory, async=async)
OperationalError: could not connect to server: Connection refused
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
当我重新启动服务器并发出后续请求时,我的测试数据得到了正常响应。
所以,简而言之,我不确定我可能会遗漏什么,但代码似乎对我有用。
Postgresql 9.4,psycopg2 2.6,python 2.7.9,peewee 2.6.0