SqlAlchemy - Flask集成SqlAlchemy
一、sqlalchemy 简介
1 sqlalchemy
在Flask中没有orm【对象关系映射】框架,方便我们快速操作数据库。但是在Flask,fastapi中用sqlalchemy居多
SQLAlchemy是一个基于Python实现的ORM框架。该框架建立在 DB API【数据库接口规范】之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然后使用数据API执行SQL并获取执行结果
1.1 简介
SQLAlchemy是一个流行的Python ORM(Object-Relational Mapping)库,它允许Python开发人员使用Python对象来操作关系型数据库,而不需要直接编写SQL语句。
SQLAlchemy支持多种数据库,包括MySQL、PostgreSQL、SQLite和Oracle等。
1.2 使用
① 安装
pip3 install sqlalchemy
② 使用sqlalchemy 操作各种数据库
SQLAlchemy本身无法操作数据库,其必须使用pymsql等第三方插件
-
MySQL
pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] -
Oracle
cx_Oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
- 更多
http://docs.sqlalchemy.org/en/latest/dialects/index.html
1.3 原生操作
# 1 导入 from sqlalchemy import create_engine # 2 生成引擎对象 engine=create_engine( "mysql+pymysql://root:root123@127.0.0.1:3306/bbs001", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 3 使用引擎获取链接,操作数据库 conn = engine.raw_connection() cursor = conn.cursor() sql = 'select * from app01_blog;' cursor.execute(sql) print(cursor.fetchall())
1.4 创建、操作数据表
不能创建库,也不能修改字段【增加、删除字段】
# 第一步:导入 from sqlalchemy import create_engine import datetime from sqlalchemy.orm import declarative_base from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index # 第二步:执行declarative_base 得到一个类 Base = declarative_base() # 第三步:继承生成的base类 class good_list(Base): # 第四步:写字段 id = Column(Integer, primary_key=True) # 生成一列,类型是Integer,主键 name = Column(String(32), index=True, nullable=False) # name列varchar32,索引,不可为空 category = Column(String(32), unique=True) # unique不可重复 create_time = Column(DateTime, default=datetime.datetime.now) desc = Column(Text, nullable=True) # 第五步:写表名 如果不写以类名为表名 __tablename__ = 'goods' # 数据库表名称 # 第六步:联合建立索引 __table_args__ = ( # 联合唯一 UniqueConstraint('id', 'name', name='unix_id_name'), # 索引 Index('index_cate_name', 'name', 'category'), ) class Book(Base): __tablename__ = 'books' id = Column(Integer, primary_key=True) name = Column(String(32)) # 第七步:把表同步到数据库中 engine = create_engine( "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 把表同步到数据库 (把被Base管理的所有表,都创建到数据库) # 创建表 # Base.metadata.create_all(engine) # 删除表 Base.metadata.drop_all(engine)
1.5 sqlalchemy快速插入数据
使用orm插入
1 使用engine对象 2 生成session对象 3 拿到session对象 4 增加数据 "插入数据:使用orm" from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from models import Book # 1 生成orm对象 engine = create_engine( "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 2 拿到一个session类,绑定engine Session = sessionmaker(bind=engine) # 3 拿到session对象,相当于连接对象(session会话) session = Session() # 4 增加数据 book = Book(name='咖啡') session.add(book) # 5 提交数据 ,关闭session对象 session.commit() session.close()
2 scoped_session线程安全
2.1 基本使用
生成的session会话是全局的,在多线程中会出现数据错乱的问题,导致线程的安全问题。
想要生成线程是安全的,可以使用内部的local对象,取代当前线程的session,如果当前线程中有local那么就直接使用,没有则新创建一个
from sqlalchemy.orm import scoped_session from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 1 生成session对象 engine = create_engine( "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 2 拿到session类,闯入engine对象 Session = sessionmaker(bind=engine) # session = Session() 这样创建的session 会有线程不安全的问题 # 生成的session会话是全局的,在多线程中会出现数据错乱的问题,导致线程的安全问题 # 想要生成线程是安全的,可以使用内部的local对象,取代当前线程的session, # 如果当前线程中有local那么就直接使用,没有则新创建一个 # 在sqlalchemy中使用了scoped_session的对象 session = scoped_session(Session)
2.2 类装饰器
scoped_session的对象,没有session中的方法,比如add
、commit
等等,但是可以使用加在类上的装饰器,给这个类增加属性或者方法
这样scoped_session的对象,就可以使用Session类中的方法
def run(): print('run方法') def wrapper(my_class): def inner(*args,**kwargs): obj = my_class(*args,**kwargs) # my_class 类的对象增加 run方法 obj.run = run return obj return inner @wrapper class Duck: pass if __name__ == '__main__': obj = Duck() # 给类添加了装饰器后,可以给类的对象新增run方法 obj.run()
二、 基本增删改查和高级查询
1 基本增删改查
(1) 查
filter
中写表达式filter_by
直接写等式
① 查询所有all 返回普通列表
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from models import Good, Book # 生成orm对象 engine = create_engine( "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 拿到一个session类,绑定engine Session = sessionmaker(bind=engine) session = Session() "查询" res = session.query(Book).all() sql_sent = session.query(Book) # 不加all() 返回执行的sql语句 print(res) # 返回的是普通列表中 套对象 [<models.Book object at 0x10419da00>] # # 如果在表模型中重写了__repr__方法,则可以定制列表的返回格式 [咖啡, 黑咖啡] print
② 查询某几个字段
# select name as xx,id from book res = session.query(Book.name.label('xx'),Book.id).all() print(res) ret = session.query(Book.name.label('xx'),Book.id) for i in ret: print(i)
③ filter和filter_by
filter:传的是表达式, filter_by 传的是参数
res = session.query(Book).filter(Book.name == '咖啡').all() print(res) ret = session.query(Book).filter(Book.name != '咖啡').all() print(ret)
④ 取了all()
之后,结果是一个普通列表list,但是list没有first方法
res = session.query(Book).all().first() print(res) --------- AttributeError: 'list' object has no attribute 'first'
⑤ 查询所有,使用占位符
text()中使用字符串,使用 :value :name
占位符和.params()
传递参数
res = session.query(Book).filter(text('id<:value and name=:name')).params(value=10,name='咖啡').all() print(res)
⑥ 自定义查询
from_statement 写纯原生sql res=session.query(User).from_statement(text("SELECT * FROM users where email=:email")).params(email='3@qq.com').all() # print(type(res[0])) # 是book的对象,但是查的是User表 不要这样写 print(res[0].name) #
(2) 增
-
add()
增加单个对象 -
add_all()
增加一个列表[对象1,对象2,...]
"增" good1 = Good(name='拿铁',category='咖啡',create_time=datetime.datetime.now(),desc='咖啡1') good2 = Good(name='可口可乐',category='饮料',create_time=datetime.datetime.now(),desc='饮料') book = Book(name='三国志') session.add_all([good1,good2,book]) session.commit()
(3) 删
filter
或filter_by
查询的结果 不要all
或first
,直接点 .delete()
即可
delete后返回的结果是影响的数据库中的行数
good = session.query(Good).filter(Good.id > 7).all() res= session.query(Good).filter(Good.id > 7).delete() session.commit() # 1 print(good) print(res)
(4) 改
① 方式1:update方法
# 方式1 update res = session.query(Good).filter_by(id=7).update({'name':'美式咖啡'}) session.commit()
② 方式2:使用对象修改
good = session.query(Good).filter_by(id=7).first() good.name='拿铁咖啡' session.add(good) # add 如果有主键,就是修改,如果没有主键就是新增 session.commit()
2 高级查询
① and条件连接
条件之间用 逗号
连接
res = session.query(Book).filter(Book.id < 3, Book.name == '咖啡').all() print(res)
② 范围查询:between关键字
res = session.query(Book).filter(Book.id.between(1,9)).all() print(res)
③ in条件连接
由于in
在python中是关键字,所以sqlalchemy
用in_
表示in
res = session.query(Good).filter(Good.id.in_([1,3,5])).all() print(res) # [phone, computer]
④ ~条件连接
~
表示非,除。。外
res = session.query(Good).filter(~Good.id.in_([1,3,5])).all() print(res) # [sound]
⑤ and 、or条件
from sqlalchemy import and_,or_ # and res = session.query(Good).filter(and_(Good.id<3,Good.name=='phone')).all() print(res) # [phone] # or res = session.query(Good).filter(or_(Good.id>1,Good.name=='phone')).all() print(res) # [phone, sound, computer]
⑥ 通配符 与like搭配
%
:匹配任意长度的任意字符。_
:匹配任意单个字符。[]
:匹配指定字符集中的任意一个字符。例如,[aeiou]
表示匹配任意一个元音字母,[0-9]
表示匹配任意一个数字。[^]
:匹配除指定字符集外的任意一个字符。例如,[^aeiou]
表示匹配任意一个非元音字母。
res = session.query(Good).filter(Good.name.like('p%')).all() print(res)
⑦ 分页
# 一页放3条数据,查第7页 # 条 t 页 s # [t*s:t*s+t] res = session.query(Good)[3 * 7:3 * 7 + 3]
⑧ 排序 order_by 分组后排序
res = session.query(Good).order_by(Good.id.desc()).all() # desc降序 print(res) # [computer, sound, phone] ret = session.query(Good).order_by(Good.id.asc()).all() # asc升序 print(ret) # 2 先按照一个条件排序后,再按第二个条件排序 # res = session.query(Good).order_by(Good.id.desc(),Good.create_time.asc()).all() res = session.query(Good).order_by(Good.id.desc()).all() print(res) # [computer, sound, phone]
⑨ 分组查询 group_by
五个聚合函数max min sum count计数 avg
res = session.query(Good,func.min(Good.id)).group_by(Good.desc)
⑩ 分组之后的过滤 having
res = session.query(Good,func.max(Good.id),func.min(Good.id)).group_by(Good.desc).having(func.max(Good.id))
3 使用原生sql语句
3.1 在sqlalchemy中使用原生sql
(1) 方式1:使用引擎对象连接数据库,生成游标对象执行sql语句
" 方式1" # 1 导入 from sqlalchemy import create_engine # 2 生成引擎对象 engine = create_engine( "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", max_overflow=0, # 超过连接池大小外最多创建的连接 pool_size=5, # 连接池大小 pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) ) # 3 使用引擎获取连接,操作数据库 conn = engine.raw_connection() cursor = conn.cursor() # 4 编写sql语句 sql_sent = 'select * from goods' cursor.execute(sql_sent) print(cursor.fetchall())
(2) 方式2:通过session对象来执行sql语句
" 方式1" # # 1 导入 # from sqlalchemy import create_engine # # 2 生成引擎对象 # engine = create_engine( # "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", # max_overflow=0, # 超过连接池大小外最多创建的连接 # pool_size=5, # 连接池大小 # pool_timeout=30, # 池中没有线程最多等待的时间,否则报错 # pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置) # ) # # 3 使用引擎获取连接,操作数据库 # conn = engine.raw_connection() # cursor = conn.cursor() # # # 4 编写sql语句 # sql_sent = 'select * from goods' # cursor.execute(sql_sent) # # print(cursor.fetchall()) "方式2" from models import Good, Book from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import scoped_session # 1 生成引擎engine对象 engine = create_engine( "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test" ) # 2 生成session对象 Session = sessionmaker(bind=engine) session = scoped_session(Session) # 3 通过session的execute方法来执行sql语句,并提交 cursor = session.execute(text('insert into books(name) value (:book_name)'),params={'book_name':'围城'}) session.commit() print(cursor.lastrowid) # 返回最后一行数据的id session.close()
3.2 在django中使用原生sql
``表名.objects.raw(sql)`执行sql语句,但是如果查询的不是模型表中的字段,而是其他表中的字段也可以查找到不会报错,但是会乱套不推荐使用
def index(request): res = Book.objects.raw('select * from app01_publish where id=1') # RawQuerySet 用起来跟列表一样 print(res[0]) print(type(res[0])) print(res[0].name) # book 没有addr,但是也打印出来了 print(res[0].addr) return HttpResponse('ok')
4 表关系:一对多
4.1 表模型的创建
relationship跟数据库无关,不会新增字段,只用于快速连表操作,backref用于反向查询
# 一对多关系 from sqlalchemy import create_engine import datetime from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index from sqlalchemy.orm import relationship # 第二步:执行declarative_base,得到一个类 Base = declarative_base() class Hobby(Base): __tablename__ = 'hobby' id = Column(Integer, primary_key=True) caption = Column(String(50), default='篮球') class Person(Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) name = Column(String(32), index=True, nullable=True) # hobby指的是tablename而不是类名 # 关联字段写在多的一方,写在Person中,跟hobby表中id字段做外键关联 hobby_id = Column(Integer, ForeignKey("hobby.id")) # 跟数据库无关,不会新增字段,只用于快速链表操作 # 基于对象的跨表查询:就要加这个字段,取对象 person.hobby pserson.hobby_id # 类名,backref用于反向查询 hobby = relationship('Hobby', backref='pers') # 如果有hobby对象,拿到所有人 hobby.pers def __repr__(self): return self.name engine = create_engine("mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", ) # 把表同步到数据库 (把被Base管理的所有表,都创建到数据库) Base.metadata.create_all(engine) # 把所有表删除 # Base.metadata.drop_all(engine)
4.2 新增
(1)新增方式1:通过表模型来新增
① 不带外键
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import scoped_session from models2 import Hobby, Person # 1 生成引擎对象 engine = create_engine("mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", ) # 2 生成session对象 Session = sessionmaker(bind=engine) session = scoped_session(Session) "一对多新增:通过模型对象来新增,但是外键之间不会关联" # 1 生成模型对象 hobby = Hobby(caption='购物') # 2 session.add新增 session.add(hobby) person = Person(name='石购物') session.add(person) # 3 提交 session.commit()

② 带外键
"新增:带外键" hobby = session.query(Hobby).filter(Hobby.caption=='购物').first() person = Person(name='孙燕姿',hobby_id=hobby.id) session.add(person) session.commit()
(2)新增方式2:按对象的方式新增
支持按对象的增加方式,必须加relationship 做关联
① 新增一个对象
新增的对象有与之通过relationship
字段关联的表后,就可以直接传入对象来新增
hobby = session.query(Hobby).filter(Hobby.caption == '听歌').first() person = Person(name='王力宏', hobby=hobby) session.add(person) session.commit()
② 新增多个对象
当多个对象都没有的时候,可以用add_all()
方法来新增列表中的对象
hobby = Hobby(caption='吃饭') person = Person(name='胡吃饭', hobby=hobby) session.add_all([hobby, person]) session.commit()
4.3 基于对象的查询
(1) 正向查询:查询有relationship
字段的表
person = session.query(Person).filter(Person.name =='王听歌').first() print(person) # 王听歌 print(person.hobby) # 听歌 print(person.hobby.id) # 1 print(person.hobby_id) # 1
(2) 反向查询:查询没有relationship
字段的表,按照backref属性查询
由于是一对多关系,所以反向查询时,返回的是列表
hobby = session.query(Hobby).filter(Hobby.id==4).first() # 反向查询时,点 的是relationship字段的 backref=pers 属性 print(hobby) # 购物 print(hobby.pers) # [石购物, 孙燕姿] 由于是一对多反向查询时,返回的是列表 for person in hobby.pers: print(person.name)
5 表关系:多对多
5.1 表模型
多对多的表模型,表与表之间的关系的第三章表,需要我们手动创建
外键字段放在那一张表中都可以
# 一对多关系 from sqlalchemy import create_engine from sqlalchemy.orm import declarative_base from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index from sqlalchemy.orm import relationship # 第二步:执行declarative_base,得到一个类 Base = declarative_base() # 多对多 # 中间表 手动创建 class Boy2Girl(Base): __tablename__ = 'boy2girl' id = Column(Integer, primary_key=True, autoincrement=True) girl_id = Column(Integer, ForeignKey('girl.id')) boy_id = Column(Integer, ForeignKey('boy.id')) class Girl(Base): __tablename__ = 'girl' id = Column(Integer, primary_key=True) name = Column(String(64), unique=True, nullable=False) def __str__(self): return self.name def __repr__(self): return self.name class Boy(Base): __tablename__ = 'boy' id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(64), unique=True, nullable=False) # 与生成表结构无关,仅用于查询方便,放在哪个单表中都可以 # 方便快速查询,写了这个字段,相当于django 的manytomany,快速使用基于对象的跨表查询 girls = relationship('Girl', secondary='boy2girl', backref='boys') def __str__(self): return self.name def __repr__(self): return self.name engine = create_engine("mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", ) # 把表同步到数据库 (把被Base管理的所有表,都创建到数据库) Base.metadata.create_all(engine) # 把所有表删除 # Base.metadata.drop_all(engine)
5.2 新增
(1) 新增方式1:通过表模型来新增
girl = Girl(name='丽桑卓') boy = Boy(name='马尔扎哈') # 先生成模型对象,新增模型对象后在创建他们之间的关系 session.add_all([girl, boy]) session.commit() # 在关系表中创建关系 session.add(Boy2Girl(girl_id=1, boy_id=1)) session.commit()
(2)新增方式2:按对象的方式新增
使用relationship
来创建对象,这样新增的对象,在两张表中都会新增数据,并且会在第3张关系表中自动新增好彼此的关系
boy = Boy(name='派克') boy.girls = [Girl(name='阿狸'), Girl(name='厄运')] session.add(boy) session.commit()
5.3 基于对象的跨表查询
由于关系是多对多,所以查询出来的结果都是列表
(1) 正向查询:查询有relationship
字段的表
boy = session.query(Boy).filter(Boy.id == 2).first() print(boy.girls) # [阿狸, 厄运]
(2) 反向查询:查询没有relationship
字段的表,按照backref属性查询
girl = session.query(Girl).filter(Girl.id == 2).first() # 使用relationship字段中的 backref属性 print(girl.boys) # [派克]
6 连表查询
(1) 指定字段连接
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import scoped_session from models2 import Person,Hobby # 1 生成引擎对象 engine = create_engine("mysql+pymysql://root:root123@127.0.0.1:3306/flask_test", ) # 2 生成session对象 Session = sessionmaker(bind=engine) session = scoped_session(Session) "指定字段连接" res = session.query(Person,Hobby).filter(Person.hobby_id==Hobby.id).all() print(res) # [(王听歌, 听歌), (李打游戏, 打游戏), (张看电影, 看电影), (赵听歌, 听歌), (石购物, 购物), (孙燕姿, 购物), (王力宏, 听歌), (胡吃饭, 吃饭)]
三、 Flask集成sqlalchemy
1 flask-sqlalchemy:操作数据库
1.1 简介
flask中一般使用flask-sqlalchemy来操作数据库,使用起来比较简单,易于操作,操作数据库需要先创建一个db对象
1.2 快速使用
(1)安装
pip install flask-sqlalchemy
(2)Flask中快速使用
① 导入flask-sqlalchemy
from flask_sqlalchemy import SQLAlchemy
② 实例化得到db对象
db = SQLAlchemy()
③ 将db注册到app中
db.init_app(app)
④ 视图函数中使用session
此时的session已经是线程安全的了,不会出现多线程中数据混乱的问题了
from session_sql import session @app.route('/') def index(): session.add(Book(name='金萍媒')) session.commit() session.close() return '增加成功'
⑤ models.py 中继承db.Model
字段使用db对象中自带的db.Column
、db.Integer
、db.ForeignKey
# 导入db对象 from manage import db # 多对多 # 中间表 手动创建 class Boy2Girl(db.Model): __tablename__ = 'boy2girl' id = db.Column(db.Integer, primary_key=True, autoincrement=True) girl_id = db.Column(db.Integer, db.ForeignKey('girl.id')) boy_id = db.Column(db.Integer, db.ForeignKey('boy.id')) class Girl(db.Model): __tablename__ = 'girl' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True, nullable=False) def __str__(self): return self.name def __repr__(self): return self.name class Boy(db.Model): __tablename__ = 'boy' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(64), unique=True, nullable=False) girls = db.relationship('Girl', secondary='boy2girl', backref='boys')
⑥ 在Flask项目的配置文件中配置好
- manage.py中
app.config.from_pyfile('settings.py')
- settings.py中
SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:root123@127.0.0.1:3306/flask_test?charset=utf8" SQLALCHEMY_POOL_SIZE = 5 SQLALCHEMY_POOL_TIMEOUT = 30 SQLALCHEMY_POOL_RECYCLE = -1 # 追踪对象的修改并且发送信号 SQLALCHEMY_TRACK_MODIFICATIONS = False
(3)配置项说明
配置选项 | 说明 |
---|---|
SQLALCHEMY_DATABASE_URI |
连接数据库。示例:mysql://username:password@host/post/db?charset=utf-8 |
SQLALCHEMY_BINDS |
一个将会绑定多种数据库的字典。 更多详细信息请看官文 绑定多种数据库. |
SQLALCHEMY_ECHO |
调试设置为true |
SQLALCHEMY_POOL_SIZE |
数据库池的大小,默认值为5。 |
SQLALCHEMY_POOL_TIMEOUT |
连接超时时间 |
SQLALCHEMY_POOL_RECYCLE |
自动回收连接的秒数。 |
SQLALCHEMY_MAX_OVERFLOW |
控制在连接池达到最大值后可以创建的连接数。当这些额外的 连接回收到连接池后将会被断开和抛弃。 |
SQLALCHEMY_TRACK_MODIFICATIONS |
如果设置成 True (默认情况),Flask-SQLAlchemy 将会追踪对象的修改并且发送信号。这需要额外的内存, 如果不必要的可以禁用它。 |
2 flask-migrate库:表的映射
创建好表后,修改表的字段,需要映射到数据库,原生的sqlalchemy,不支持修改表的字段,需要用到flask-migrate
库
2.1 快速使用
提前需要安装flask:2.2.2 , flask-script:2.0.3
(1)安装flask-migrate
pip3 install flask-migrate==2.7.0
(2)注册flask-migrate和修改启动文件
① 在app所在文件中导入
from flask_script import Manager, Server from flask_migrate import Migrate, MigrateCommand
② 生成manager对象,管理app和数据库
manager = Manager(app) Migrate(app, db) manager.add_command('db', MigrateCommand) # 创建数据库映射命令 # manager.add_command('start',Server(port=6666,use_debugger=True)) # 创建启动命令
③ 修改app.run()
为 manager.run()
以后使用python manage.py runserver 启动项目
python3 manage.py runserver
④ flask-migrate中的命令
python manage.py db init # 生成一个migrations文件夹,里面以后不要动,记录迁移的编号
执行了 init
命令后,会出现一个migrations文件夹,其中包括了数据库迁移的记录
- 以后在models.py 写表,加字段,删字段,改参数
# 以后在models.py 写表,加字段,删字段,改参数 > python manage.py db migrate # 记录 > python manage.py db upgrade # 与数据同步
3 flask项目演示
# 0 创建数据库 movie # 1 pycharm打开项目 # 3 在models中,注释,解开注释,右键执行,迁移表 # 4 在models中恢复成原来的 # 5 在命令行中python manage.py runserver运行项目 # 6 访问前台和后台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY