初识flask——数据库(2015.6.13)
来源:互联网 发布:百度推广软件 编辑:程序博客网 时间:2024/06/05 03:17
这章数据库的内容比较多(一个一个代码敲下来的啊),主要涉及数据库的配置,博客的数据库结构设计以及数据库的操作。
和django不一样的地方是flask的数据库管理使用的是Flask-SQLAlchemy扩展,而django使用的是内置的数据库系统,更新到1.7之后也自带了migration系统还蛮方便的。
一、数据库的配置
包括配置,建立数据库,迁移,升级和降级三个部分。
1.配置(config.py)
import osbasedir = 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')
小型的应用我们使用sqlite数据库。SQLALCHEMY_DATABASE_URI 是 Flask-SQLAlchemy 扩展需要的。这是我们数据库文件的路径。 SQLALCHEMY_MIGRATE_REPO 是文件夹,我们将会把 SQLAlchemy-migrate 数据文件存储在这里。
2.初始化数据库(app/__init__.py中添加)
from flask import Flaskfrom flask.ext.sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config.from_object('config')db = SQLAlchemy(app)from app import views, models
创建了一个 db 对象,这是我们的数据库,接着导入一个新的模块,叫做 models。我们在models中编写代码来描述博客系统中的对象在数据库中的存储形式。这些内容在后面再写,接下来是数据库的创建,管理和维护。
在models编写完成并且格式无误之后,便可以应用models来创建数据库了,SQLAlchemy-migrate 包自带命令行和 APIs,这些 APIs 以一种将来允许容易升级的方式来创建数据库。然而在命令行中输入代码不太方便,在这里我们编写几个脚本来进行相关的操作。
3.创建数据库(db_create.py)
from migrate.versioning import apifrom config import SQLALCHEMY_DATABASE_URIfrom config import SQLALCHEMY_MIGRATE_REPOfrom app import dbimport os.pathdb.create_all()if not os.path.exists(SQLALCHEMY_MIGRATE_REPO): api.create(SQLALCHEMY_MIGRATE_REPO, 'database repository') api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)else: api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, api.version(SQLALCHEMY_MIGRATE_REPO))
代码中我们导入了SQLAlchemy提供的api,初始化时创建的db对象,以及数据库和迁移文件的存储路径。
后面一堆的意思是我想是先创建一个数据库,然后如果不存在数据库的存储文件夹,就创建一个,并且将它和数据库绑定起来,如果有一个就直接绑定(大约是这个意思吧(:з」∠))
注意:存储库是不会再生的,如果它已经存在。这将使我们重新创建数据库,同时保留现有的存储库,如果我们需要。
4.第一次迁移(db_migrate.py)
我们会把应用程序数据库的结构任何的改变看做成一次迁移,因此这是我们第一次迁移,我们将从一个空数据库迁移到一个能存储用户的数据库上。
import impfrom migrate.versioning import apifrom app import dbfrom config import SQLALCHEMY_DATABASE_URIfrom config import SQLALCHEMY_MIGRATE_REPOmigration = SQLALCHEMY_MIGRATE_REPO + '/versions/%03d_migration.py' % (api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) + 1)tmp_module = imp.new_module('old_model')old_model = api.create_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)exec old_model in tmp_module.__dict__script = api.make_update_script_for_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, tmp_module.meta, db.metadata)open(migration, "wt").write(script)api.upgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)print 'New migration saved as ' + migrationprint 'Current database version: ' + str(api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO))
在这段代码中,导入了一些配置文件,定义了迁移文件的存储位置,migration,中间那段代码应该是把新旧数据模型作对比的然而并不太懂。两者间的不同将会被记录成一个迁移脚本存放在迁移仓库中。迁移脚本知道如何去迁移或撤销它,所以它始终是可能用于升级或降级一个数据库。
5.数据库升级和回退(db_upgrade.py,db_downgrade.py)
from migrate.versioning import apifrom config import SQLALCHEMY_DATABASE_URIfrom config import SQLALCHEMY_MIGRATE_REPOapi.upgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)print 'Current database version: ' + str(api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO))
可以看出api直接提供了一个upgrade方法来完成这项操作。
回退同理:
from migrate.versioning import apifrom config import SQLALCHEMY_DATABASE_URIfrom config import SQLALCHEMY_MIGRATE_REPOv = api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)api.downgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, v - 1)print 'Current database version: ' + str(api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO))
这个脚本运行一次将会使数据库回退一个版本。
关于数据库的操作主要就是这些,接下来我们将数据库和我们有关于博客的数据模型结合起来,没错 ,就是前面提到的models.。
二、数据模型设计及实例操作
1.数据模型定义(models.py)
from app import dbROLE_USER = 0ROLE_ADMIN = 1class User(db.Model): id = db.Column(db.Integer, primary_key = True) nickname = db.Column(db.String(64), unique = True) email = db.Column(db.String(120), unique = True) role = db.Column(db.SmallInteger, default = ROLE_USER) posts = db.relationship('Post', backref = 'author', lazy = 'dynamic') def __repr__(self): return '<User %r>' % (self.nickname)class Post(db.Model): id = db.Column(db.Integer, primary_key = True) body = db.Column(db.String(140)) timestamp = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __repr__(self): return '<Post %r>' % (self.body)
在这里我们定义了User和Post两个类,代表用户和博文两个对象。
其中用户对象有id,nickname,email,role几个基本字段,而posts是和Post对象有关联的字段,它是被构建成一个db.relationship字段。这并不是一个实际的数据库字段,对于一个一对多(一个用户会有多篇博文)的关系,db.relationship字段通常是定义在“一”这一边。在这种关系下,我们得到一个 user.posts 成员。
而在后面的Post类中,Post对象有id,body,timestamp,user_id几个属性,其中user_id是一个外键,它链接到User的id字段,用来表示Post的作者。和User中的posts是相对应的。
2.数据库操作
我们已经按照数据模型的内容把数据库创建完成了,但是这个数据库现在还是空的没有任何内容,下面我们来操作一些实例。
在数据库文件的同级目录下打开python console,再导入数据库和我们在数据模型中定义好的模块。
>>> from app import db>>> from app.models import User, Post, ROLE_USER, ROLE_ADMIN
①创建一个新用户
>>> u1 = User(nickname='john', email='john@email.com', role=ROLE_USER)>>> db.session.add(u1)>>> db.session.commit()
第一句实例化一个用户对象,后面两句表示在会话中添加这个用户对象和提交(感觉和git有点像)。
在会话的上下文中完成对数据库的更改。多个的更改可以在一个会话中累积,当所有的更改已经提交,你可以发出一个 db.session.commit(),这能原子地写入更改。如果在会话中出现错误的时候, db.session.rollback() 可以是数据库回到会话开始的状态。如果即没有 commit 也没有 rollback 发生,系统默认情况下会回滚会话。会话保证数据库将永远保持一致的状态。
②查询
>>> users = User.query.all()>>> print users [<User u'john'>, <User u'susan'>]>>> for u in users: ... print u.id,u.nickname ... 1 john 2 susan
对于查询用户,我们使用 query 成员,这是对所有模型类都是可用的。
根据字段查询可以像这样:
>>> u = User.query.get(1)>>> print u <User u'john'>
③提交一篇blog
>>> import datetime>>> u = User.query.get(1)>>> p = Post(body='my first post!', timestamp=datetime.datetime.utcnow(), author=u)>>> db.session.add(p)>>> db.session.commit()
你可能注意到了我们并没有设置 user_id 字段。相反我们在 author 字段上存储了一个 User 对象。ORM 层将会知道怎么完成 user_id 字段。
④删除数据
>>> users = User.query.all()>>> for u in users:... db.session.delete(u)...>>> posts = Post.query.all()>>> for p in posts:... db.session.delete(p)...>>> db.session.commit()
- 初识flask——数据库(2015.6.13)
- 初识flask——模板的使用(2015.5.22)
- 初识flask——表单(2015.5.24)
- 用flask开发个人博客(22)—— 使用Flask-Migrate实现数据库的更新
- 初识docker—创建WEB应用容器1python+flask
- flask 初识
- 数据库—初识
- Flask Web Development —— 数据库(中)
- flask搭建个人博客(二)——骨架、数据库
- Flask系列教程(4)——SQLAlchemy数据库
- Flask学习——数据库迁移
- 数据库原理与设计(一)——初识数据库
- Flask系列教程(7)——Flask-Script
- Flask系列教程(8)——Flask-Migrate
- Flask系列教程(9)——Flask-WTF
- 初识数据库(二)——数据库系统
- Python Flask Web 第十一课 —— 使用 Flask-SQLAlchemy 管理数据库
- 初识FLASK路由
- 边学习边实践才是硬道理=a=
- Win7/Vista Hook CreateProcess 的特别之处
- Learning Perl总结提升
- java 为何会出现框架
- 定位未导出的函数地址(SHCreateProcess)
- 初识flask——数据库(2015.6.13)
- 整理关于css中position与float的一些用法
- 自制MyEclipse豆沙绿主题
- Gradle代码混淆文件个人收藏版
- iOS 中间显示透明圆
- C++在VS2008的IDE环境中操作Excel2007(基础)
- c语言常见错误与注意点
- 多渠道打包build.gradle收藏版
- 【Linux学习】epoll详解