这是我正在使用的:
/myproject
README.md
runserver.py
/myproject
__init__.py
api.py
/resources
__init__.py
foo.py
bar.py
/common
__init__.py
db.py
/tests
test_myproject.py
这里没有什么特别的。大部分内容可以在Flask-RESTful用户指南的Intermediate Usage页面中找到。
我的关注点是循环导入...
api.py
from flask import Flask
from flask_restful import Api
app = Flask(__name__)
from myproject.resources.foo import Foo
from myproject.resources.bar import Bar
api = Api(app)
api.add_resource(Foo, '/Foo', '/Foo/<str:id>')
api.add_resource(Bar, '/Bar', '/Bar/<str:id>')
foo.py
from flask_restful import Resource
from myproject.common.db import query_db
class Foo(Resource):
def get(self):
pass
def post(self):
pass
db.py
from flask import g
import sqlite3
from myproject.api import app
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = sqlite3.connect(app.config['DATABASE'])
db.row_factory = make_dicts
return db
def query_db(query, args=(), one=False):
cur = get_db().execute(query, args)
rv = cur.fetchall()
cur.close()
return (rv[0] if rv else None) if one else rv
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.commit()
db.close()
显然,我在项目中引入了循环导入:
api.py -> foo.py -> db.py -> api.py
只要在导入资源之前实例化Flask应用程序对象(我已经这样做了),这不是一个大问题。类似的模式在这里讨论(请参见页面底部的循环导入部分)。 我的问题是... 这是一种构建Flask-RESTful项目的好方法吗? 这里是关于此主题的最接近的SO问题。我对提供的答案不满意,因为我不想将数据库函数保留在顶层
__init__.py
文件中(或在路由所属的api.py
中)。以下是几个类似的SO问题,但它们处理导入错误(我没有遇到这些问题): 结构Flask-Restful API以使用SQLAlchemy
db.py
仍然依赖于api.py
。请查看带有@app.teardown_appcontext
装饰器的close_connection
函数。 - jamesdarabiinit
函数中将close_connection
声明为全局变量,否则Python会将其视为局部变量。其次,当我尝试使用此方法时,我收到以下错误:ProgrammingError: Cannot operate on a closed database.
- jamesdarabiProgrammingError
的位置吗? - junnytony