flask插件系列之SQLAlchemy基础使用
sqlalchemy是一个操作关系型数据库的ORM工具。下面研究一下单独使用和其在flask框架中的使用方法。
直接使用sqlalchemy操作数据库
安装sqlalchemy
pip install sqlalchemy
初始化及操作数据库
# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# 创建对象的基类:
Base = declarative_base()
class User(Base):
'''用戶信息表'''
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String(80), unique=True)
email = Column(String(320), unique=True)
password = Column(String(32), nullable=False)
user = User(username='ming', email='dddd', password='1234567')
# 初始化数据库连接:
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)
# 创建单个会话
session = DBSession()
session = db_session()
session.add(user)
session.commit()
session.close()
# 通过创建会话池连接
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
session = db_session()
session.add(user)
session.commit()
session.close()
# 也可以创建连接
con = engine.connect()
con.execute("一个表对象",name='ffff',email='dddd', password='1234567')
con.close()
在flask框架中集成使用
安装
pip install Flask-SQLAlchemy
- 如果需要操作mysql数据库,还需要安装pymysql;
pip install pymysql
配置文件
- Flask-SQLAlchemy可以将关于SQLAlchemy的配置集成到flask的配置文件中去,在初始化app的时候一起加载。相关的配置键有:
SQLALCHEMY_DATABASE_URI
用于连接数据的数据库。例如:
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://caiwp:mysql@192.168.1.23:3307/tms_mysql?charset=utf8'
其格式为:mysql://username:password@server/db?编码
注意默认使用mysqldb连接数据库,要使用pymysql就需要用mysql+pymysql的格式;
SQLALCHEMY_COMMIT_ON_TEARDOWN
设置是否在每次连接结束后自动提交数据库中的变动。
example:
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_BINDS
一个映射绑定 (bind) 键到 SQLAlchemy 连接 URIs 的字典。他可以用来连接多个数据库。
example:
SQLALCHEMY_BINDS = {
'users': 'mysqldb://localhost/users',
'appmeta': 'sqlite:////path/to/appmeta.db'
}
# 上面除了默认的连接外,又连接了两个数据库,分别命名users,appmeta。在创建模型的时候可以为相应的操作定制化;
# 更多的详细参考:http://www.pythondoc.com/flask-sqlalchemy/binds.html#binds
SQLALCHEMY_ECHO
如果设置成 True,SQLAlchemy 将会记录所有发到标准输出(stderr)的语句,这对调试很有帮助;默认为false;
如:
SQLALCHEMY_ECHO = True
SQLALCHEMY_RECORD_QUERIES
可以用于显式地禁用或者启用查询记录。查询记录 在调试或者测试模式下自动启用。
一般我们不设置。
SQLALCHEMY_NATIVE_UNICODE
可以用于显式地禁用支持原生的unicode。
SQLALCHEMY_POOL_SIZE
数据库连接池的大小。默认是数据库引擎的默认值 (通常是 5)。
如:
SQLALCHEMY_POOL_SIZE = 10
SQLALCHEMY_TRACK_MODIFICATIONS
如果设置成 True (默认情况),Flask-SQLAlchemy 将会追踪对象的修改并且发送信号。这需要额外的内存,如果不必要的可以禁用它。
example:
SQLALCHEMY_TRACK_MODIFICATIONS = Flase
SQLALCHEMY_MAX_OVERFLOW
控制在连接池达到最大值后可以创建的连接数。当这些额外的连接使用后回收到连接池后将会被断开和抛弃。保证连接池只有设置的大小;
如:
SQLALCHEMY_MAX_OVERFLOW = 5
SQLALCHEMY_POOL_TIMEOUT
指定数据库连接池的超时时间。默认是 10。
example:
SQLALCHEMY_POOL_TIMEOUT = 10
SQLALCHEMY_POOL_RECYCLE
自动回收连接的秒数。这对MySQL是必须的,默认情况下MySQL会自动移除闲置8小时或者以上的连接,Flask-SQLAlchemy会自动地设置这个值为 2 小时。也就是说如果连接池中有连接2个小时被闲置,那么其会被断开和抛弃;
手动设置:
SQLALCHEMY_POOL_RECYCLE = 1200
常用配置
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://caiwp:mysql@192.168.1.23:3307/tms_mysql?charset=utf8'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
# 下面两项调试阶段启动,部署时关闭
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_ECHO = True
常用的字段、关系类型
- 常用的字段
类型名 python类型 说明
Integer int 普通整数,一般是32位
SmallInteger int 取值范围小的整数,一般是16位
BigInteger int或long 不限制精度的整数
Float float 浮点数
Numeric decimal.Decimal 普通整数,一般是32位
String str 变长字符串
Text str 变长字符串,对较长或不限长度的字符串做了优化
Unicode unicode 变长Unicode字符串
UnicodeText unicode 变长Unicode字符串,对较长或不限长度的字符串做了优化
Boolean bool 布尔值
Date datetime.date 时间
Time datetime.datetime 日期和时间
LargeBinary str 二进制文件
Enum enum 枚举类型
- 常用列选项
primary_key 如果为True,代表表的主键
unique 如果为True,代表这列不允许出现重复的值
index 如果为True,为这列创建索引,提高查询效率
nullable 如果为True,允许有空值,如果为False,不允许有空值
default 为这列定义默认值,如default=1
- 常用的关系选项
backref 在关系的另一模型中添加反向引用,用于找到父表
primary join 明确指定两个模型之间使用的联结条件
uselist 如果为False,不使用列表,而使用标量值
order_by 指定关系中记录的排序方式
secondary 指定多对多中记录的排序方式
secondary join 在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件
创建模型类
from flask.ext.sqlalchemy import SQLAlchemy
# 指定一个字段为外键,必须使用类
from sqlalchemy.schema import ForeignKey
# 创建一个db对象
db = SQLAlchemy()
class User(db.Model):
__bind_key__ = 'xxx' # 可以指定为哪个数据库定义表
__tablename__ = 'users' # 定义表的名字
# 定义表中的列字段,接收所有相关的对字段的定义的信息
id = db.Column(db.Integer, primary_key=True) # 如果第一个参数是一个字符串,那么使用该字符串作为字段名
username = db.Column(db.String(80), unique=True)
# 定义相关联的表,backref为Address赋予了一个新的属性,让Address可以通过address.person找到user表
addresses = db.relationship('Address', backref='person',
lazy='dynamic')
# 可以手动初始化,也可以不做,那么会自动使用字段的变量名作为字段名
def __init__(self, username, email):
self.username = username
self.email = email
# 输出字符串
def __repr__(self):
return '<User %r>' % self.username
class Address(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(50))
# 指定外键
person_id = db.Column(db.Integer, db.ForeignKey('person.id'))
#也可以直接创建表,一般用于多对多关系
tags = db.Table('uesrs',
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
)
引入上下文
SQLAlchemy是一个全局对象,如果有多个应用程序的话,必须要让SQLAlchemy对象知道当前服务于哪个app。
# 如果只有一个app,可以创建时初始化
app = Flask(__name__)
db = SQLAlchemy(app)
# 如果有多个应用
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
# 这个函数其读取app的配置参数,将和数据库相关的配置加载到SQLAlchemy对象中
db.init_app(app)
return app
数据库的操作
- 创建和删除表
# 删除所有的表,bind参数可以指定为哪一个数据库创建表,默认为__all__,所有的数据库;
# app传入是为了获取初始化的相关参数,如果db已经初始化,则不需要传入
db.drop_all(bind="",app=app)
# 创建所有的表,其参数和drop_all是一样的
db.create_all()
- 数据的增删改查
# 首先创建一个实例
user = User(username='aaa')
# 插入一条数据,这时会发出一条insert语句,但是该事务还没有提交,可以放弃
# 每个add操作都是一个数据
db.session.add(user)
# 批量添加数据
db.session.add_all([user1,user2])
# 删除数据
db.session.delete(user1)
# 提交给数据库
db.session.commit()
# 更新数据
User.query.filter_by(name='xxx').update({'name':'li'})
# 查询query属性
User.query.filter().all()
- 过滤器的使用
# 常用的过滤器
filter() 把过滤器添加到原查询上,返回一个新查询
filter_by() 把等值过滤器添加到原查询上,返回一个新查询
limit() 使用指定的值限定原查询返回的结果
offset() 偏移原查询返回的结果,返回一个新查询
order_by() 根据指定条件对原查询结果进行排序,返回一个新查询
group_by() 根据指定条件对原查询结果进行分组,返回一个新查询
# 精确查询
person = User.query.filter_by(name='aaa',id='23').all()
# 模糊查询,
persons = User.query.filter(User.name.endswith('g')).all()
User.query.filter(User.id>3).all()
# 按username排序
User.query.order_by(User.username)
# 限制返回3个数据
User.query.limit(3).all()
# 条件查询
# 逻辑非
User.query.filter(User.name!='xxx').all()
# 逻辑与
from sqlalchemy import and_
User.query.filter(and_(User.name!='xxx',User.address.endwith('g')).all()
# 逻辑或
User.query.filter(or_(User.name!='xxx',User.address.endwith('g'))).all()
# 取反,名字不是xxx的所有
User.query.filter(not_(User.name=='xxx')).all()
- 执行器的使用
all() 以列表形式返回查询的所有结果
first() 返回查询的第一个结果,如果未查到,返回None
first_or_404() 返回查询的第一个结果,如果未查到,返回404
get() 返回指定主键对应的行,如不存在,返回None
get_or_404() 返回指定主键对应的行,如不存在,返回404
count() 返回查询结果的数量
paginate() 返回一个Paginate对象,它包含指定范围内的结果
# 使用主键查询,id = 1
User.query.get(1)
数据库的迁移
我们可以使用create_all()函数来创建数据库的表,不过在flask中有更加完善的管理工具flask-migrate;
安装
pip install flask-migrate
- 实例
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate,MigrateCommand
from flask_script import Shell,Manager
app = Flask(__name__)
manager = Manager(app)
db = SQLAlchemy(app)
#第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例
migrate = Migrate(app,db)
#manager是Flask-Script的实例,这条语句在flask-Script中添加一个db命令
manager.add_command('db',MigrateCommand)
# 生成相关的迁移文件,创建migrations文件夹,这个文件在项目的目录下
python manage.py db init
# 生成迁移脚本,生成upgrade()和downgrade()函数的内容,这是将要执行的操作;
python manage.py db migrate -m '修改说明'
#更新数据库
python manage.py db upgrade
# 如果需要历史版本,回退
python manage.py db history # 先查询历史版本
# 执行回退
python manage.py db downgrade 版本号
参考:
flask插件系列之SQLAlchemy基础使用的更多相关文章
- flask插件系列之SQLAlchemy实用技巧
下面记录一下SQLAlchemy使用的技巧. 在多模块下定义models 如果由多个蓝图下读定义了model模块,在初始化的时候需要加载到上下文中. 当使用flask_Migrate迁移数据库的时候, ...
- flask插件系列之flask_session会话机制
flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制. 配置参数详解 SESSION_COOKIE_NAME 设置返回给客户端的c ...
- flask插件系列之flask_uploads上传文件
前言 flask可以实现上传文件和下载文件的基本功能,但如果想要健壮的功能,使用flask_uploads插件是十分方便的. 安装 pip install flask_uploads 基本使用 # e ...
- flask插件系列之Flask-WTF表单
flask_wtf是flask框架的表单验证模块,可以很方便生成表单,也可以当做json数据交互的验证工具,支持热插拔. 安装 pip install Flask-WTF Flask-WTF其实是对w ...
- flask插件系列之flask_caching缓存
前言 为了尽量减少缓存穿透,同时减少web的响应时间,我们可以针对那些需要一定时间才能获取结果的函数和那些不需要频繁更新的视图函数提供缓存服务,可以在一定的时间内直接返回结果而不是每次都需要计算或者从 ...
- flask插件系列之flask_restful设计API
前言 flask框架默认的路由和视图函数映射规则是通过在视图函数上直接添加路由装饰器来实现的,这使得路由和视图函数的对应关系变得清晰,但对于统一的API开发就变得不怎么美妙了,尤其是当路由接口足够多的 ...
- flask插件系列之flask_celery异步任务神器
现在继续学习在集成的框架中如何使用celery. 在Flask中使用celery 在Flask中集成celery需要做到两点: 创建celery的实例对象的名字必须是flask应用程序app的名字,否 ...
- flask插件系列之flask_cors跨域请求
前后端分离在开发调试阶段本地的flask测试服务器需要允许跨域访问,简单解决办法有二: 使用flask_cors包 安装 pip install flask_cors 初始化的时候加载配置,这样就可以 ...
- Flask插件系列之flask_celery
现在继续学习在集成的框架中如何使用celery. 在Flask中使用celery 在Flask中集成celery需要做到两点: 创建celery的实例对象的名字必须是flask应用程序app的名字,否 ...
随机推荐
- [LeetCode] Climbing Sairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
- HDU4497——GCD and LCM
这个题目挺不错的,看到是通化邀请赛的题目,是一个很综合的数论题目. 是这样的,给你三个数的GCD和LCM,现在要你求出这三个数有多少种可能的情况. 对于是否存在这个问题,直接看 LCM%GCD是否为0 ...
- BZOJ4719 NOIP2016天天爱跑步(线段树合并)
线段树合并的话这个noip最难题就是个裸题了. 注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里. #include<iostream> #inc ...
- Contest 3
A:非常裸的dp. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstrin ...
- 【BZOJ1758】【WC2010】重建计划(点分治,单调队列)
[BZOJ1758][WC2010]重建计划(点分治,单调队列) 题面 BZOJ 洛谷 Description Input 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表 ...
- Alpha 冲刺 —— 十分之一
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作,对多个目标检测及文字识别模型进行评估.实验,选取较 ...
- 阿里云 centos7 tomcat 启动巨慢的解决方法(几分钟)
方法一: 通过修改Tomcat启动文件-Djava.security.egd=file:/dev/urandom 通过修改JRE中的java.security文件securerandom.source ...
- 去除sql表格中的unique 唯一属性----phpmyadmin 没发现哪里好直接操作
ALTER TABLE tf_giftcard_record DROP INDEX oid;
- 「Django」与mysql8连接的若干问题
1.setting配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', #数据库驱动名 'NAME': 'my_tes ...
- 「Python-Django」Django中使用数据库的 9 个小技巧
Django 中使用数据库的 9 个小技巧. 1. 过滤器聚合 在 Django 2.0 之前,如果你想得到“用户总数”.“活跃用户总数”等信息时,你不得不使用条件表达式. Django 2.0 中, ...