Flask-RESTful项目结构

时间:2015-06-11 04:05:49

标签: 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

这里没什么特别的。其中大部分内容可以在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应用程序对象,这不是问题。讨论了类似的模式here(参见页面底部的循环导入部分)。

我的问题......

这是构建Flask-RESTful项目的好方法吗?

This是我能找到的关于这个主题的最接近的SO问题。我对提供的答案不满意,因为我不想将我的数据库功能保存在顶级__init__.py文件中(或api.py - 路由所属的位置)。

以下是其他几个类似的SO问题,但它们正在处理导入错误(我不是):

Structure Flask-Restful API to use SQLAlchemy

Error importing models when trying to run app

1 个答案:

答案 0 :(得分:2)

由于您的问题基于意见,我将建议我认为更好的解决方案:)

不是在plt.legend(handles=[red_patch,blue_line]) 中导入plt.legend([red_patch,blue_line]) ,而是在myproject.api.app中创建我自己的模块级全局变量来存储数据库配置:

<强> db.py

db.py

然后在db.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() 初始化db

<强> api.py

api.py

这种方式myproject.common.db.init()不再依赖from flask import Flask from flask_restful import Api from myproject.common import db app = Flask(__name__) db.init(app) ....