Flask中的数据库
Flask本身并不支持数据库。意味着可以自由选择适合应用程序的数据库。
在Python中对于数据库,有很多选择,并且很多带有Flask扩展,可很好地与Flask Web应用程序集成。数据库分为两大类:关系型、非关系型。后者称为NoSQL,即它们没有实现流行的关系查询语言SQL。关系型数据库适合具有结构化数据的应用程序,如用户列表、博客帖子等;而NoSQL数据库适合具有结构不太明确的。
展示了第一个Flask扩展 Flask-WTF。本章将再使用两个Flask扩展:Flask-SQLAlchemy、Flask-Migrate。
其中,Flask-SQLAlchemy为流行的SQLAlchemy包提供了一个Flask-friendly包装器,它是一个ORM。ORM允许应用程序使用高级实体(如类、对象、方法)而不是表和SQL来管理数据库,它的工作是将高级操作转换为数据库命令。
关于SQLAlchemy的好处是:它不是一个ORM,而是许多关系数据库。SQLAlchemy支持很多数据库引擎,包括流行的MySQL、PostgreSQL、SQLite。这非常强大,因为可以使用不需要服务器的简单SQLite数据库进行开发,然后在生产服务器上部署应用程序时,可以选择更强大的MySQL或PostgreSQL服务器,而无需改变应用程序。
PS:学到一个单词 alchemy 译为 炼金术、魔力,SQLAlchemy是个有魔力的东西。
在虚拟环境中安装Flask-SQLAlchemy:pip install flask-sqlalchemy,将会自动附带安装sqlalchemy包。
更多关于Flask-SQLAlchemy、SQLAlchemy以及Flask使用数据库的操作可查看博文。
数据库迁移
大多数数据库教程都涵盖数据库的创建、使用,但没有充分解决在应用程序在需要更改或增长时对现有数据库进行更新的问题。这是一个难点,因为关系数据库是以结构化数据为中心,在结构发生更改时,数据库中已有的数据需要迁移到修改后的结构中。
Flask-Migrate扩展是Alembic(PS:Alembic是SQLAlchemy作者编写的数据库迁移工具)的Flask包装器,是SQLAlchemy的数据库迁移框架。虽然使用数据库迁移为启动数据库添加了一些工作,但这是一个很小的代价,将为未来对数据库进行更改提供强大方法。
在虚拟环境中安装Flask-Migrate:pip install flask-migrate,将会自动附带安装Mako、alembic、python-dateutil、python-editor、six。
Flask-SQLAlchemy配置
在开发过程中,这将使用SQLite数据库,它是开发小型应用程序的方便选择,有时甚至不是那么小,因为每个数据库都存储在磁盘上的单个文件中,并且不需要运行像MySQL、PostgreSQL的数据库服务器。
添加两个配置项到config.py中:
microblog/config.py:Flask-SQLAlchemy配置
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
class Config(object):
#.......
#格式为mysql+pymysql://数据库用户名:密码@数据库地址:端口号/数据库的名字?数据库格式
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@localhost:3306/flaskblog?charset=utf8'
#如果你不打算使用mysql,使用这个连接sqlite也可以
#SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR,'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
Flask-SQLAlchemy扩展从SQLALCHEMY_DATABASE_URI变量中获取应用程序数据库的位置。在第3章中已学过,从环境变量中设置配置是一种很好的做法,并在环境中未定义变量时提供回退值。在这种情况下,将从DATABASE_URL环境变量中获取数据库URL;如果没有定义,将在应用程序主目录下配置一个名为app.db的数据库,该数据库存储在basedir变量中。
SQLALCHEMY_TRACK_MODIFICATIONS配置选项设置为False,意为禁用我不需要的Flask-SQLAlchemy的该特征,即追踪对象的修改并且发送信号。
更多的Flask-SQLAlchemy配置选项可参考 官网。
数据库将在应用程序中通过数据库实例表示。数据库迁移引擎也将有一个实例。这些是需要在应用程序之后需要创建的对象(即在app/__init__.py)。
app/__init__.py:初始化Flask-SQLAlchemy和Flask-Migrate,更新代码
from flask import Flask
from config import Config#从config模块导入Config类
from flask_sqlalchemy import SQLAlchemy#从包中导入类
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)#数据库对象
migrate = Migrate(app, db)#迁移引擎对象
from app import routes,models#导入一个新模块models,它将定义数据库的结构,目前为止尚未编写
from app import db
#数据库类
class User(db.Model):
__tablename__='user'
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(64),index=True,unique=True)
email=db.Column(db.String(120),index=64,unique=True)
password_hash=db.Column(db.String(128))
def __repr__(self):
return 'user:{}'.format(self.name)
同时参考:https://blog.csdn.net/u014793102/article/details/80378543
# back是反向引用,User和Post是一对多的关系,backref是表示在Post中新建一个属性author,关联的是Post中的user_id外键关联的User对象。
#lazy属性常用的值的含义,select就是访问到属性的时候,就会全部加载该属性的数据;joined则是在对关联的两个表进行join操作,从而获取到所有相关的对象;dynamic则不一样,在访问属性的时候,并没有在内存中加载数据,而是返回一个query对象, 需要执行相应方法才可以获取对象,比如.all()
遇到的坑:https://blog.csdn.net/u014793102/article/details/80378543
Flask_SQLAlchemy文档可学习到更多查询数据库的知识。
flask对于数据库的操作
from app import db
from app.models import User,Post
# 添加数据到数据库
user1=User(username='tom',email='123455@112')
db.session.add(user1)
db.session.commit()
# # 查询数据
users=User.query.all()
for i in users:
print(i.username+':'+i.email)
# 查询单条数据
u=User.query.get(1)
print(u)
#带有外键关联的数据表
# 1)插入数据
u=User.query.get(2)
# #将User对象与Post建立关系
p=Post(body='第2次提交的内容',author=u)
db.session.commit()
# 2)查询一对多的关系
#知道1如何查出对应的多
u=User.query.get(1)
posts=u.posts.all()
print(posts)
#知道多查出对应的1
posts=Post.query.all()
for p in posts:
print(p.author.username)
#数据删除
user=User.query.all()
for u in user:
db.session.delete(u)
db.session.commit()