在 flask 中使用 SQLAlchemy

在 flask 中, 很多人更喜歡通過 SQLAlchemy 來操作數據庫。這種情況下推薦使用包代替模塊, 把數據模型剝離到一個獨立的模塊中。這樣的做法不是必須的, 但是更加合理。

Flask-SQLAlchemy Extension

由於 SQLAlchemy 是一個通用的數據庫抽象層和 ORM, 它需要一些額外的配置, Flask 中有一個擴展來處理這些。

Declarative

SQLAchemy 中的 declarative extension 是最近出現的一種方法。這種方法允許你一次性定義表單和數據模型, 這和 Django 的工作方式類似。

下面是一個 database.py 模塊的例子:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    # import all modules here that might define models so that
    # they will be registered properly on the metadata.  Otherwise
    # you will have to import them first before calling init_db()
    import yourapplication.models
    Base.metadata.create_all(bind=engine)

我們自己定義的數據模型只需要繼承上面代碼中的 Base 就可以了。這個地方不用擔心線程安全的問題,因爲 SQLAlchemy 已經通過 scoped_session 幫我們處理了。

我們只需要把下面的代碼放入我們的應用模塊中就可以以 declarative 的方式來使用 SQLAlchemy 了。Flask 會在 request 結束或者應用退出時自動關閉 session:

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

下面的代碼是一個數據模型的例子(可以放入 models.py中, e.g.):

from sqlalchemy import Column, Integer, String
from yourapplication.database import Base

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r>' % (self.name)

創建數據庫的時候可以使用 init_db():

>>> from yourapplication.database import init_db
>>> init_db()

向數據庫中插入記錄:

>>> from yourapplication.database import db_session
>>> from yourapplication.models import User
>>> u = User('admin', 'admin@localhost')
>>> db_session.add(u)
>>> db_session.commit()

查詢也很簡單:

>>> User.query.all()
[<User u'admin'>]
>>> User.query.filter(User.name == 'admin').first()
<User u'admin'>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章