### 导航
- [索引](# "总目录")
- [下一页](# "上传文件") |
- [上一页](# "在 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
- 许可证
- 术语表