這裏是我的工作:瓶的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用戶指南的頁面上找到。
我關心的是圓形的進口...
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
這不是一個大問題,只要我實例化瓶應用對象之前導入我的資源(我做)。 here討論了類似的模式(參見頁面底部的循環導入部分)。
我的問題...
這是一個很好的方式來構建一個瓶的RESTful項目?
This是我可以找到的關於此主題最接近的SO問題。我對所提供的答案並不滿意,因爲我不想將我的數據庫功能保留在頂層__init__.py
文件中(或者在api.py
--路由所屬的地方)。
這裏有幾個其他類似的SO問題,但它們與進口處理錯誤(這我不是):
Structure Flask-Restful API to use SQLAlchemy
Error importing models when trying to run app
感謝您的答覆的依賴。我喜歡你的解決方案,但是,'db.py'仍然會依賴'api.py'。請參閱'@ app.teardown_appcontext'裝飾器的'close_connection'函數。 – jamesdarabi
如果你不介意手動應用裝飾器,那麼可以很容易地解決這個問題:)。看到我上面的編輯。 – junnytony
首先,我認爲你需要在'init'函數中將'close_connection'聲明爲全局的,否則Python會將它視爲一個局部變量。其次,當我嘗試這種方法時,出現以下錯誤:'ProgrammingError:無法在封閉數據庫上運行。「 – jamesdarabi