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基础使用的更多相关文章

  1. flask插件系列之SQLAlchemy实用技巧

    下面记录一下SQLAlchemy使用的技巧. 在多模块下定义models 如果由多个蓝图下读定义了model模块,在初始化的时候需要加载到上下文中. 当使用flask_Migrate迁移数据库的时候, ...

  2. flask插件系列之flask_session会话机制

    flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制. 配置参数详解 SESSION_COOKIE_NAME 设置返回给客户端的c ...

  3. flask插件系列之flask_uploads上传文件

    前言 flask可以实现上传文件和下载文件的基本功能,但如果想要健壮的功能,使用flask_uploads插件是十分方便的. 安装 pip install flask_uploads 基本使用 # e ...

  4. flask插件系列之Flask-WTF表单

    flask_wtf是flask框架的表单验证模块,可以很方便生成表单,也可以当做json数据交互的验证工具,支持热插拔. 安装 pip install Flask-WTF Flask-WTF其实是对w ...

  5. flask插件系列之flask_caching缓存

    前言 为了尽量减少缓存穿透,同时减少web的响应时间,我们可以针对那些需要一定时间才能获取结果的函数和那些不需要频繁更新的视图函数提供缓存服务,可以在一定的时间内直接返回结果而不是每次都需要计算或者从 ...

  6. flask插件系列之flask_restful设计API

    前言 flask框架默认的路由和视图函数映射规则是通过在视图函数上直接添加路由装饰器来实现的,这使得路由和视图函数的对应关系变得清晰,但对于统一的API开发就变得不怎么美妙了,尤其是当路由接口足够多的 ...

  7. flask插件系列之flask_celery异步任务神器

    现在继续学习在集成的框架中如何使用celery. 在Flask中使用celery 在Flask中集成celery需要做到两点: 创建celery的实例对象的名字必须是flask应用程序app的名字,否 ...

  8. flask插件系列之flask_cors跨域请求

    前后端分离在开发调试阶段本地的flask测试服务器需要允许跨域访问,简单解决办法有二: 使用flask_cors包 安装 pip install flask_cors 初始化的时候加载配置,这样就可以 ...

  9. Flask插件系列之flask_celery

    现在继续学习在集成的框架中如何使用celery. 在Flask中使用celery 在Flask中集成celery需要做到两点: 创建celery的实例对象的名字必须是flask应用程序app的名字,否 ...

随机推荐

  1. [LeetCode] [LeetCode] Populating Next Right Pointers in Each Node II

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  2. poj3041 Asteroids(二分图最小顶点覆盖、二分图匹配)

    Description Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape o ...

  3. element-ui中单独引入Message组件的问题

    import Message from './src/main.js'; export default Message; 由于Message组件并没有install 方法供Vue来操作的,是直接返回的 ...

  4. 【BZOJ4443】小凸玩矩阵(二分答案,二分图匹配)

    [BZOJ4443]小凸玩矩阵(二分答案,二分图匹配) 题面 BZOJ Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两 ...

  5. NAT网络地址转换模拟过程

    原理图,如图1 图1 以下为配置NAT网络地址转换的实验: eNSP模拟图,如图2 图2 Step1.给路由器的每个接口赋予一个地址,如图3,图4 图3 图4 AR1和AR2中添加路由表项,如图5,图 ...

  6. 光荣之路测试开发面试linux考题之四:性能命令

    Hi,大家好我是tom,I am back.今天要给大家讲讲linux系统一些性能相关命令. 1.fdisk 磁盘管理 是一个强大的危险命令,所有涉及磁盘的操作都由该命令完成,包括:新增磁盘.增删改磁 ...

  7. 使当前对象相对于上层DIV 水平、垂直居中定位

    <!doctype html> <html> <head> <meta http-equiv="content-type" content ...

  8. WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)复现

    WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)                                                -----by  ba ...

  9. C++11——引入的新关键字

    1.auto auto是旧关键字,在C++11之前,auto用来声明自动变量,表明变量存储在栈,很少使用.在C++11中被赋予了新的含义和作用,用于类型推断. auto关键字主要有两种用途:一是在变量 ...

  10. Spring MVC 向前台页面传值-ModelAndView

    ModelAndView 该对象中包含了一个model属性和一个view属性 model:其实是一个ModelMap类型.其实ModelMap是一个LinkedHashMap的子类 view:包含了一 ...