### 導航
- [索引](# "總目錄")
- [下一頁](# "上傳文件") |
- [上一頁](# "在 Flask 中使用 SQLite 3") |
- [Flask 0.10.1 文檔](#) ?
- [Flask 代碼模式](#) ?
# 在 Flask 中使用 SQLAlchemy
很多人更傾向于使用 [SQLAlchemy](http://www.sqlalchemy.org/) [http://www.sqlalchemy.org/] 進行數據庫操作。在這種情況下,建議您使用包的而不是模塊的方式組織您的應用代碼,并將所有的模型放置到一個單獨的模塊中([*大型應用*](#))。盡管這并非必要,但是這么做將會讓程序的結構更加明晰。
使用 SQLAlchemy 有四種常用的方法,我們在下面列出了這幾種方法的基本使用框架:
### Flask-SQLAlchemy 擴展
因為 SQLAlchemy 是一個常用的數據庫抽象層和數據庫關系映射包(ORM),并且需要一點點設置才可以使用,因此存在一個 Flask 擴展幫助您操作它。如果您想要快速開始使用,那么我們建議您使用這種方法。
您可以從 [PyPI](http://pypi.python.org/pypi/Flask-SQLAlchemy) [http://pypi.python.org/pypi/Flask-SQLAlchemy]下載到 [Flask-SQLAlchemy](http://packages.python.org/Flask-SQLAlchemy/) [http://packages.python.org/Flask-SQLAlchemy/]
### 顯式調用
SQLAlchemy 中的 declarative 擴展是最新的使用 SQLAlchemy 的方法。它允許您同時定義表和模型,就像 Django 一樣工作。除了下文所介紹的內容外,我們建議您參考 [declarative](http://www.sqlalchemy.org/docs/orm/extensions/declarative.html) [http://www.sqlalchemy.org/docs/orm/extensions/declarative.html] 擴展的官方文檔。
這是一個 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():
# 在這里導入所有的可能與定義模型有關的模塊,這樣他們才會合適地
# 在 metadata 中注冊。否則,您將不得不在第一次執行 init_db() 時
# 先導入他們。
import yourapplication.models
Base.metadata.create_all(bind=engine)
~~~
為了定義您的模型,僅僅構造一個上面代碼編寫的 Base 類的子類。如果您好奇為何我們在這里不用擔心多線程的問題(就像我們在先前使用 [g](# "flask.g")對象操作 SQLite3 的例子一樣):那是因為 SQLAlchemy 已經在scoped_session 類當中為我們完成了這些任務。
在您的應用當中以一個顯式調用 SQLAlchemy , 您只需要將如下代碼放置在您應用的模塊中。Flask 將會在請求結束時自動移除數據庫會話:
~~~
from yourapplication.database import db_session
@app.teardown_request
def shutdown_session(exception=None):
db_session.remove()
~~~
這是一個模型的例子(將代碼放入 models.py 或類似文件中):
~~~
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'>
~~~
### 手動實現 ORM
手動實現 ORM (對象關系映射) 相比前面的顯式調用方法,既有一些優點,也有一些缺點。主要差別在于這里的數據表和模型是分開定義的,然后再將其映射起來。這提供了更大的靈活性,但是會增加了代碼量。通常來說它和上面顯式調用的工作的方式很相似,所以請確保您的應用已經被合理分割到了包中的不同模塊中。
這是一個 database.py 模塊的例子:
~~~
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData()
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
def init_db():
metadata.create_all(bind=engine)
~~~
與顯式調用相同,您需要在請求結束后關閉數據庫會話。將下面的代碼放到您的應用程序模塊中:
~~~
from yourapplication.database import db_session
@app.teardown_request
def shutdown_session(exception=None):
db_session.remove()
~~~
下面是一個數據表和模型的例子(將他們放到 models.py 當中):
~~~
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from yourapplication.database import metadata, db_session
class User(object):
query = db_session.query_property()
def __init__(self, name=None, email=None):
self.name = name
self.email = email
def __repr__(self):
return '<User %r>' % (self.name)
users = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(50), unique=True),
Column('email', String(120), unique=True)
)
mapper(User, users)
~~~
查詢和插入操作和上面所給出的例子是一樣的。
### SQL 抽象層
如果您僅用到數據庫系統和 SQL 抽象層,那么您只需要引擎部分:
~~~
from sqlalchemy import create_engine, MetaData
engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
metadata = MetaData(bind=engine)
~~~
然后您就可以像上文的例子一樣聲明數據表,或者像下面這樣自動加載他們:
~~~
users = Table('users', metadata, autoload=True)
~~~
您可以使用 insert 方法插入數據,我們需要先獲取一個數據庫連接,這樣我們就可以使用“事務”了:
~~~
>>> con = engine.connect()
>>> con.execute(users.insert(), name='admin', email='admin@localhost')
~~~
SQLAlchemy 將會為我們自動提交對數據庫的修改。
查詢數據可以直接通過數據庫引擎,也可以使用一個數據庫連接:
~~~
>>> users.select(users.c.id == 1).execute().first()
(1, u'admin', u'admin@localhost')
~~~
返回的結果也是字典樣式的元組:
~~~
>>> r = users.select(users.c.id == 1).execute().first()
>>> r['name']
u'admin'
~~~
您也可以將 SQL 語句的字符串傳入到execute() 函數中:
~~~
>>> engine.execute('select * from users where id = :1', [1]).first()
(1, u'admin', u'admin@localhost')
~~~
更多 SQLAlchemy 相關信息,請參考 [其網站](http://sqlalchemy.org/) [http://sqlalchemy.org/].
? 版權所有 2013, Armin Ronacher.
- 歡迎使用 Flask
- 前言
- 給有經驗程序員的前言
- 安裝
- 快速入門
- 教程
- 介紹 Flaskr
- 步驟 0: 創建文件夾
- 步驟 1: 數據庫模式
- 步驟 2: 應用設置代碼
- 步驟 3: 創建數據庫
- 步驟 4: 請求數據庫連接
- 步驟 5: 視圖函數
- 步驟 6: 模板
- 步驟 7: 添加樣式
- 福利: 應用測試
- 模板
- 測試 Flask 應用
- 記錄應用錯誤
- 配置處理
- 信號
- 即插視圖
- 應用上下文
- 請求上下文
- 用藍圖實現模塊化的應用
- Flask 擴展
- 與 Shell 共舞
- Flask 代碼模式
- 大型應用
- 應用程序的工廠函數
- 應用調度
- 使用 URL 處理器
- 部署和分發
- 使用 Fabric 部署
- 在 Flask 中使用 SQLite 3
- 在 Flask 中使用 SQLAlchemy
- 上傳文件
- 緩存
- 視圖裝飾器
- 使用 WTForms 進行表單驗證
- 模板繼承
- 消息閃現
- 用 jQuery 實現 Ajax
- 自定義錯誤頁面
- 延遲加載視圖
- 在 Flask 中使用 MongoKit
- 添加 Favicon
- 數據流
- 延遲請求回調
- 添加 HTTP Method Overrides
- 請求內容校驗碼
- 基于 Celery 的后臺任務
- 部署選擇
- mod_wsgi (Apache)
- 獨立 WSGI 容器
- uWSGI
- FastCGI
- CGI
- 聚沙成塔
- API
- JSON 支持
- Flask 中的設計決策
- HTML/XHTML 常見問題
- 安全注意事項
- Flask 中的 Unicode
- Flask 擴展開發
- Pocoo 風格指引
- Python 3 支持
- 升級到最新版本
- Flask Changelog
- 許可證
- 術語表