鍍金池/ 問答/HTML5  Python  數(shù)據(jù)庫/ 動態(tài)綁定flask-sqlalchemy的model

動態(tài)綁定flask-sqlalchemy的model

背景

用Flask實(shí)現(xiàn)一個REST微服務(wù),多個結(jié)構(gòu)相同的MySQL數(shù)據(jù)庫對應(yīng)著同一個Model。需要根據(jù)請求,在不同的數(shù)據(jù)庫中作查詢并返回結(jié)果。

已完成的工作

根據(jù)官方文檔配置了SQLALCHEMY_BINDS,如:

SQLALCHEMY_BINDS = {
        'db01': 'mysql://...',
        'db02': 'mysql://...',
        'db03': 'mysql://...'
    }

查詢時根據(jù)請求中包含的數(shù)據(jù)庫名稱字段動態(tài)查詢:

...
engine = db.get_engine(bind=db_name) #綁定數(shù)據(jù)庫
DBSession = sessionmaker(bind=engine)
db_session = DBSession()
result = db_session.query(db_model).filter(...).all()
db_session.close()
...

問題

現(xiàn)在不單單要提供RESTful API,還要做一個將查詢結(jié)果分頁展示的前端頁面,查閱資料可以用flask-sqlalchemy支持的paginate()來做。然而問題來了,我上面這樣調(diào)用db_session.query()得到的Query對象是flask-sqlalchemy的Query父類,不支持paginate()方法。想要調(diào)用paginate()應(yīng)該是:

result = db_model.query.filter_by(...).paginate()

而Model默認(rèn)的bind應(yīng)該來自app.config中的SQLALCHEMY_DATABASE_URI,我這里為None必然導(dǎo)致拋出異常。這樣一來,engine/bind的初始化又該在哪里做?而要動態(tài)地改變db_model的bind,又該如何實(shí)現(xiàn)呢?

回答
編輯回答
刮刮樂

前端頁面的這個分頁功能的數(shù)據(jù)庫固定嗎?
如果固定的話,可以在 Model 里面加上 __bind_key__ = 'db01'

如果不固定的話,換個思路,根據(jù)你上面的 query 自己實(shí)現(xiàn)一個paginate()

2017年1月23日 23:36
編輯回答
礙你眼

我現(xiàn)在遇到了類似的問題,一個flask項目,現(xiàn)在的需求是創(chuàng)建一個工程需要動態(tài)的創(chuàng)建一個數(shù)據(jù)庫,然后同樣表結(jié)構(gòu)的model遷移到這個新的數(shù)據(jù)庫,用戶所有的增刪改查操作都在這個新的數(shù)據(jù)庫搞.應(yīng)該怎么弄呢

2018年8月15日 09:29
編輯回答
舊顏

這里必須修改一下 Flask-SQLAlchemy 的源碼。

Flask-SQLAlchemy 的源碼只有一個 __init__.py 源文件,大約 1000 行,修改起來很容易。找到 SQLAlchemy class 的 __init__() 方法,加入中文注釋下面那句即可:

def __init__(self, app=None, use_native_unicode=True, session_options=None, metadata=None):
    if session_options is None:
        session_options = {}
    session_options.setdefault('scopefunc', connection_stack.__ident_func__)
    self.use_native_unicode = use_native_unicode
    self.app = app
    # 使用 BaseQuery,這樣可以讓使用 db.session.query 等方法創(chuàng)建的 Query 對象支持 BaseQuery 的方法
    session_options['query_cls'] = BaseQuery

我寫過一篇文章 在 Flask-SQLAlchemy 中聯(lián)表查詢 ,其中有一個部分介紹了分頁支持。可以參考。

2017年10月21日 21:36