jam*_*abi 5 python sqlite rest flask flask-restful
这是我正在处理的内容:
/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
Run Code Online (Sandbox Code Playgroud)
这里没什么特别的。其中大部分内容可以在Flask-RESTful 用户指南的中级用法页面上找到。
我担心的是循环进口......
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>')
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
数据库.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()
Run Code Online (Sandbox Code Playgroud)
显然,我已经在我的项目中引入了循环导入:
api.py -> foo.py -> db.py -> api.py
Run Code Online (Sandbox Code Playgroud)
只要我在导入资源之前实例化 Flask 应用程序对象(我就是这么做的),这就不是什么大问题。此处讨论了类似的模式(请参阅页面底部的循环导入部分)。
我的问题...
这是构建 Flask-RESTful 项目的好方法吗?
这是我能找到的关于这个主题的最接近的问题。我对提供的答案不满意,因为我不想将我的数据库函数保留在顶级__init__.py文件中(或api.py路由所属的位置)。
这里还有其他几个类似的问题,但它们正在处理导入错误(我不是):
由于您的问题主要是基于意见,我将提出我认为更好的解决方案:)
我将创建自己的模块级全局变量来存储数据库配置,而不是导入myproject.api.appin :db.pydb.py
数据库.py
from flask import g
import sqlite3
_db_config = None # Holds database config
def init(app):
""" Function must be called to initalize this module """
global _db_config
global close_connection
_db_config = app.config['DATABASE']
# Manually apply @app.teardown_appcontext decorator
close_connection = app.teardown_appcontext(close_connection)
def _db_connect():
if _db_config is None:
raise Exception('Call init first') # or whatever error you want
return sqlite3.connect(_db_config)
def get_db():
db = getattr(g, '_database', None)
if db is None:
db = g._database = _db_connect()
db.row_factory = make_dicts
return db
....
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.commit()
db.close()
Run Code Online (Sandbox Code Playgroud)
然后api.py通过调用初始化数据库myproject.common.db.init()
api.py
from flask import Flask
from flask_restful import Api
from myproject.common import db
app = Flask(__name__)
db.init(app)
....
Run Code Online (Sandbox Code Playgroud)
这种方式db.py不再依赖于api.py
| 归档时间: |
|
| 查看次数: |
15669 次 |
| 最近记录: |