Flask 教程,第四部分:数据库 已翻译 100%

oschina 投递于 2012/12/28 09:14 (共 30 段, 翻译完成于 01-14)
阅读 63760
收藏 16
9
加载中

这是我的在python中使用the Flask 微框架开发web程序系列的第四篇文章。本系列教程的目标是开发一个全面的围脖,姑且叫微薄吧。

这是系列文章的目录


YueXiao
YueXiao
翻译于 2013/01/08 14:15
1

回顾一下

在上一章中,我们创建了一个登录表单,并且完成了数据提交和验证的工作。

在这一章里,我们将要创建一个可以记录我们网站用户的数据库。

学习这章你需要有上一章的 微博(microblog) 程序,并且确保它能够正常的运行。 

zzxworld
zzxworld
翻译于 2013/01/08 18:35
1

命令行方式运行Python脚本

在这个章节中,我们将写一些简单的数据库管理脚本。在此之前让我们来复习一下如何通过命令行方式执行Python脚本.

如果Linux 或者OS X的操作系统,需要有执行脚本的权限。例如:

chmod a+x script.py

该脚本有个指向使用解释器的命令行。再脚本赋予执行权限后就可以通过命令行执行,就像这样: like this:

./script.py <arguments>

然而,在Windows系统上这样做是不行的,你必须提供Python解释器作为必选参数,如:

flask/Scripts/python script.py <arguments>

为了避免Python解释器路径输入出错,你可以将你的文件夹microoblog/flask/Scripts添加到系统路径,确保能正常显示Python解释器。

从现在开始,在Linux/OS X上的语句简洁。如果你使用Windows系统请记得转换语句。 

YueXiao
YueXiao
翻译于 2013/01/09 10:49
2

在Flask使用数据库

我们将使用Flask-SQLAlchemy 的扩展来管理数据库。由SQLAlchemy项目提供的,已封装了关系对象映射(ORM)的一个插件。

ORMs允许数据库程序用对象的方式替代表和SQL语句。面向对象的操作被ORM转化为数据库命令。这样就意味着,不用sql语句,让Flask-SQLAlchemy为我们执行sql语句。

YueXiao
YueXiao
翻译于 2013/01/09 11:21
3

迁移

大多数数据库教程都覆盖了创建和使用一个数据库的方法,但是没有充分解决当应用程序扩展时数据库更新的问题。通常,你会删除旧的数据库,然后再创建一个新的数据库来达到更新的效果,这样就丢失了所有的数据。如果这些数据创建起来很费劲,那么我们不得不写导入导出的脚本了。

幸运的是,我们有了更好的方案.

我们现在可以使用SQLAlchemy-migrate做数据库迁移的更新了,虽然它增加了数据库启动时的负担,但这点小小的代价还是值得的,毕竟我们不用担心手动迁移数据库的问题了。

理论学习完毕,我们开始吧!

缪斯的情人
缪斯的情人
翻译于 2013/01/10 20:45
4

配置

我们的小程序使用sqlite数据库。sqlite是小程序数据库的最佳选择,一个可以以单文件存储的数据库。

在我们的配置文件中添加新的配置项 (fileconfig.py):

import os
basedir = os.path.abspath(os.path.dirname(__file__))

SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')

SQLALCHEMY_DATABASE_URI是the Flask-SQLAlchemy必需的扩展。这是我们的数据库文件的路径。

SQLALCHEMY_MIGRATE_REPO 是用来存储SQLAlchemy-migrate数据库文件的文件夹。

YueXiao
YueXiao
翻译于 2013/01/09 12:14
3

最后,初始化应用的时候也需要初始化数据库。这里是升级后的init文件(fileapp/__init):

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)

from app import views, models

注意生成的脚本已改动2个地方。我们现在开始创建数据库的adb对象,引用新的模块。马上来写这个模块。

YueXiao
YueXiao
翻译于 2013/01/08 13:47
3

数据库模型

我们在数据库存储的数据通过数据库model层被映射为一些类里面的对象,ORM层将根据类对象映射到数据库对应的字段.

让我们来创建个映射到users的model。使用WWW SQL Designer工具,我们创建了代表users表的一个图标:

users table

缪斯的情人
缪斯的情人
翻译于 2013/01/10 20:54
3

id字段通常作为主键的形式用在所有的models里面,每个在数据库中的user都有一个指定的唯一id值。幸运的是,这些都是自动的,我们只需要提供一个id字段。

nickname和email字段被定义为string类型,他们的长度也已经被指定,这样可以节省数据库存储空间。

role字段被定义为integer类型,我们用来标识users是admins还是其他类型。

缪斯的情人
缪斯的情人
翻译于 2013/01/10 21:03
4

现在我们已经明确了users表的结构,接下来转换为编码的工作将相当简单了(fileapp/models.py):

from app import db

ROLE_USER = 0
ROLE_ADMIN = 1

class User(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    nickname = db.Column(db.String(64), index = True, unique = True)
    email = db.Column(db.String(120), index = True, unique = True)
    role = db.Column(db.SmallInteger, default = ROLE_USER)

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

User类把我们刚刚创建的几个字段定义为类变量。字段使用db.Column类创建实例,字段的类型作为参数,另外还提供一些其他可选参数。例如,标识字段唯一性和索引的参数.

__repr__方法告诉Python如何打印class对象,方便我们调试使用。

缪斯的情人
缪斯的情人
翻译于 2013/01/10 21:19
5
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(34)

zsyNaCl
zsyNaCl
使用flask_sqlalchemy即可,参见http://flask-sqlalchemy.pocoo.org/2.1/quickstart/
R
RunPho
运行migrate的时候,无限报错,
exec old_model in tmp_module.__dict__
File "<string>", line9, in <module>
TypeError: object() takes no parameters
R
RunPho
我用的mysql,为啥各种编译错误。。。
zerozzxx00
zerozzxx00
TypeError: 'author' is an invalid keyword argument for Post 求解
谢谢指教

引用来自“zypy333”的评论

终于顺利运行到这里了,后面有什么不会的同学来问我

引用来自“King乀”的评论

有个问题,我在迁移数据库的时候,显示 File "./db_migrate.py", line 10 exec old_model in tmp_module.__dict__ ^ SyntaxError: Missing parentheses in call to 'exec' 求指教!

引用来自“anigm”的评论

你运行的应该是python3 exec old_model in tmp_module.__dict__ 在python3 里面应该是这样写 exec(old_model ,tmp_module.__dict__)
感谢!你的回答解决了我的问题!
xwpisme
xwpisme

引用来自“lenet”的评论

运行db_create.py时:
from migrate.versioning import api
报了:
pkg_resources.DistributionNotFound: sqlalchemy-migrate
我也遇到同样的问题,可能是版本的问题。 安装的时候用,他的setup.py安装。就 python setup.py就可以啦
测试-說不
测试-說不

引用来自“测试-老爷”的评论

[root@xu microblog]# ./app/db_create.py
Traceback (most recent call last):
File "./app/db_create.py", line 2, in <module>
from migrate.versioning import api
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/migrate/__init__.py", line 14, in <module>
pkg_resources.Requirement.parse('sqlalchemy-migrate')).version
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 197, in get_provider
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 666, in require
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 565, in resolve
pkg_resources.DistributionNotFound: sqlalchemy-migrate
运行db_create.py报错,flask-sqlalchemy和sqlalchemy-migrate都已安装
升级setuptools就没这个报错了,但是出现一个import问题,microblog/app/db_create.py中引入config报错,Traceback (most recent call last): File "./app/db_create.py", line 3, in from config import SQLALCHEMY_DATABASE_URI ImportError: No module named config
测试-說不
测试-說不
[root@xu microblog]# ./app/db_create.py
Traceback (most recent call last):
File "./app/db_create.py", line 2, in <module>
from migrate.versioning import api
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/migrate/__init__.py", line 14, in <module>
pkg_resources.Requirement.parse('sqlalchemy-migrate')).version
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 197, in get_provider
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 666, in require
File "/var/www/html/microblog/flask/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg/pkg_resources.py", line 565, in resolve
pkg_resources.DistributionNotFound: sqlalchemy-migrate
运行db_create.py报错,flask-sqlalchemy和sqlalchemy-migrate都已安装
ZhouLS
ZhouLS

引用来自“921532841”的评论

我报错 from migrate.versioning import api
最后面
File "/usr/local/lib/python2.7/site-packages/migrate/versioning/logengine.py", line 253, in __init__
super(LogEngineStrategy,self).__init__('logsql')
TypeError: __init__() takes exactly 1 argument (2 given)
都是pip install 安装的文件 不知道哪里出问题了 小白求指点
我解决了,pip install sqlalchemy-migrate 运行解决本时出现如下警告信息: /usr/local/lib/python2.7/dist-packages/flask_sqlalchemy/__init__.py:800: UserWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True to suppress this warning. warnings.warn('SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True to suppress this warning.') 解决方法是: 修改/usr/local/lib/python2.7/dist-packages/flask_sqlalchemy/__init__.py 定位到800行, 原信息如下 : track_modifications = app.config.setdefault('SQLALCHEMY_TRACK_MODIFICATIONS', None) 把None修改为True即可!!!!
ZhouLS
ZhouLS

引用来自“921532841”的评论

我报错 from migrate.versioning import api
最后面
File "/usr/local/lib/python2.7/site-packages/migrate/versioning/logengine.py", line 253, in __init__
super(LogEngineStrategy,self).__init__('logsql')
TypeError: __init__() takes exactly 1 argument (2 given)
都是pip install 安装的文件 不知道哪里出问题了 小白求指点
我也是这里出现了错误,请问你的解决了吗?如何解决的?
返回顶部
顶部