发布于2019-08-23 19:08 阅读(1918) 评论(0) 点赞(11) 收藏(1)
sqlalchemy是一个操作关系型数据库的ORM工具。下面研究一下单独使用和其在flask框架中的使用方法。
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()
pip install Flask-SQLAlchemy
pip install pymysql
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 版本号
参考:
http://flask-sqlalchemy.pocoo.org/2.3/
http://www.pythondoc.com/flask-sqlalchemy/
http://docs.jinkan.org/docs/flask/patterns/sqlalchemy.html
作者:44344df
链接:https://www.pythonheidong.com/blog/article/55840/c79d0301709b27e8fe71/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!