Flask-SQLAlchemy 和离线脚本 和 scoped_session
知识补充 在引入 init.py中的文件可以直接引入

一个对象能够执行 with方法 那么他的内部一定包含着两个方法

SQLAlchemy
作用:将SQLAlchemy相关的所有功能都封装到db=flask_sqlalchemy.SQLAlchemy()对象中

1先在settings.py中做好配置
#encoding=utf-8 class BaseConfig(object): # SESSION_TYPE = 'redis' # session类型为redis # SESSION_KEY_PREFIX = 'session:' # 保存到session中的值的前缀 # SESSION_PERMANENT = True # 如果设置为False,则关闭浏览器session就失效。 # SESSION_USE_SIGNER = False # 是否对发送到浏览器上 session:cookie值进行加密 SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/day130?charset=utf8" SQLALCHEMY_POOL_SIZE = 5 SQLALCHEMY_POOL_TIMEOUT = 30 SQLALCHEMY_POOL_RECYCLE = -1 # 追踪对象的修改并且发送信号 SQLALCHEMY_TRACK_MODIFICATIONS = False class ProductionConfig(BaseConfig): pass class DevelopmentConfig(BaseConfig): pass class TestingConfig(BaseConfig): pass
2. 在 __init__.py中实例化一个SQLAlchemy的对象
#encoding=utf-8 from flask import Flask from flask_sqlalchemy import SQLAlchemy #实例化一个SQLalchemy对象,这里边包含了sqlalchemy相关的所有操作,如创建表操作,等 db=SQLAlchemy() def creat_app(): app=Flask(__name__) from .account import account #设置配置,这里边有链接数据库的配置信息 app.config.from_object('settings.DevelopmentConfig') app.register_blueprint(account.ac) db.init_app(app) #此内容写在app.config.from_object()设置配置文件信息的后边 #因为这里边就会读取使用app的配置文件,读取SQLAlchemy相关的配置文件去,把这些配置放到db这个实例化的对象中去,进行初始化根据使用配置文件的内容去 # ,去数据库中创建表或者其他操作 return app
应用
一:.在创建表的时候会用到
如在models.py中
#!/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, UniqueConstraint, Index,DateTime,ForeignKey from s8day130 import db class Users(db.Model): #这个实际上就是实例化了 意思就是实例化的过程不用自己写了 在 __init__.py中的 db=SQLAchemey()就已经包含了这个base对他的实例化
__tablename__ = 'users' id = Column(Integer, primary_key=True,autoincrement=True) name = Column(String(32),nullable=False,unique=True)
二:- 操作表的时候也会用到
如在 account.py中
#encoding=utf-8 from flask import Blueprint,request,render_template,redirect,session from day130 import db from day130 import models ac=Blueprint('ac',__name__,template_folder="templates") @ac.route('/login',methods=["GET",'POST']) def login(): if request.method=="GET": #这里是给session中赋值呢 a=db.session.query(models.Users).all() #查询变得很简单了 print(a) return 'login'

操作:
1.在 __init__中创建实例化对象
离线脚本 完成删除


完成删除功能的py文件
drop_db.py
#encoding=utf-8 """ Web运行时,flask程序运行起来,用户通过浏览器访问 离线脚本,自定义的一个py文件(就是这个drop_table.py文件)+使用flask中定义好的功能 、(如创件好的 db 通过他来实现对setting中的链接数据库等操作的完成), """ from day130 import db from manage import creat_app #这里注意直接db.drop_all() 是不能完成删除操作的,因为flask是上下文类型的 #要基于请求,数据才会放到Local()这个对象中去,在没有请求要完成删除操作,需要用到离线脚本的只是 app=creat_app() obj=app.app_context()#AppContext(self)这个类是处理app和g的(应用上下文)
# app就是我们创建的app with obj: #能够使用with 方法,那这个对象一定有 __enter__ 方法和 __next__方法 #通过查看 得知此类中的 __enter__ 有push方法将数据放到Local()对象中 # __next__是将数据pop掉的 所以可以在此执行drop方法 db.drop_all()
当设置好这些内容后直接运行这个py文件即可
解析:AppContext内部的 __neter__方法
#通过查看 得知此类中的 __enter__ 有push方法将数据放到Local()对象中
# __next__是将数据pop掉的 所以可以在此执行drop方法

SQLAlchemy创建session的两种方式
low的写法: 这个要保证为每个线程都要创建一个session,
import models from threading import Thread from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine engine =create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/s8day128db?charset=utf8",pool_size=2,max_overflow=0) XXXXXX = sessionmaker(bind=engine) def task(): #只要有线程,就要把sesison 创建在线程里边 from sqlalchemy.orm.session import Session session = XXXXXX() #为每一个线程创建一个session data = session.query(models.Classes).all() print(data) session.close() for i in range(10): t = Thread(target=task) t.start()
方式二:
使用scrope:
更简洁,不用再去管,把创建的session放到全局变量中,只要内部一调用,就会为每个线程创建session, 不用之后 colse的时候就把你这个当前线程创建的session关闭就可以
#falsk-sesison组件默认也是用的这种方式
import models from threading import Thread from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session engine =create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/s8day128db?charset=utf8",pool_size=2,max_overflow=0)#最多开两线程,两个链接 XXXXXX = sessionmaker(bind=engine) # 原来:session=XXXXXX() """
源码解析
session = scoped_session对象 { session_factory = XXXXXX, registry = ThreadLocalRegistry{ createfunc=XXXXXX, registry=threading.local() } } """ #这样创建,就不用给每一个线程都创建session对象,由于这个类中含有threading.local() #所以能够给每个线程隔离开来,所以只实例化一个类就可以 session = scoped_session(XXXXXX) def task(): # 1. 原来的session对象 = 执行session.registry() # 2. 原来session对象.query data = session.query(models.Classes).all() print(data) session.remove() #用完之后在删除 for i in range(10): t = Thread(target=task) t.start()
源码分析

知识点补充

我们看到scoped_session这个类中没有 query方法


Flask_sqlachmy的步骤:
1. 在 __init__.py中创建db对象 from flask_sqlalchemy import SQLAlchemy # 包含了SQLAlchemy相关的所有操作 db = SQLAlchemy() 2. 在 __init__.py中create_app函数中让将app传入到db中 def create_app(): app = Flask(__name__) app.config.from_object('settings.DevelopmentConfig') from .views.account import ac app.register_blueprint(ac) # 看这里看这里 db.init_app(app) return app 3. 写配置文件,将连接字符串定义在配置文件中 SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/s8day130db?charset=utf8" SQLALCHEMY_POOL_SIZE = 5 SQLALCHEMY_POOL_TIMEOUT = 30 SQLALCHEMY_POOL_RECYCLE = -1 使用:============================================================================================ 4. 定义 s8day130_pro/models.py #!/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, UniqueConstraint, Index,DateTime,ForeignKey from s8day130_pro import db class Users(db.Model): __tablename__ = 'users' id = Column(Integer, primary_key=True,autoincrement=True) name = Column(String(32),nullable=False,unique=True) 5. 创建数据库表,编写离线脚本:drop_create_table.py from s8day130_pro import db from s8day130_pro import create_app from s8day130_pro import models app = create_app() with app.app_context(): db.drop_all() db.create_all() #data = db.session.query(models.Users).all() #print(data) 6. 在视图函数中使用SQLAlchemy操作数据库 from s8day130_pro import models from s8day130_pro import db ac = blueprints.Blueprint('ac',__name__) @ac.route('/login',methods=['GET','POST']) def login(): data = db.session.query(models.Users).all() print(data) db.session.remove() #创建完成时候吧session去掉 return 'Login'
相关文件


init.py
from flask import Flask from flask_sqlalchemy import SQLAlchemy # 包含了SQLAlchemy相关的所有操作 db = SQLAlchemy() def create_app(): app = Flask(__name__) app.config.from_object('settings.DevelopmentConfig') from .views.account import ac app.register_blueprint(ac) db.init_app(app) return app
settings.py
class BaseConfig(object): # SESSION_TYPE = 'redis' # session类型为redis # SESSION_KEY_PREFIX = 'session:' # 保存到session中的值的前缀 # SESSION_PERMANENT = True # 如果设置为False,则关闭浏览器session就失效。 # SESSION_USE_SIGNER = False # 是否对发送到浏览器上 session:cookie值进行加密 SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/s8day130db?charset=utf8" SQLALCHEMY_POOL_SIZE = 5 SQLALCHEMY_POOL_TIMEOUT = 30 SQLALCHEMY_POOL_RECYCLE = -1 # 追踪对象的修改并且发送信号 SQLALCHEMY_TRACK_MODIFICATIONS = False SECRET_KEY = "sadfasdf" class ProductionConfig(BaseConfig): pass class DevelopmentConfig(BaseConfig): DEBUG = True class TestingConfig(BaseConfig): pass
manage.py 这个主要的功能是自定义命令 >>点我
from s8day130_pro import create_app from flask_script import Manager app = create_app() manager = Manager(app) @manager.command def custom(arg): """ 自定义命令 python manage.py custom 123 :param arg: :return: """ print(arg) @manager.option('-n', '--name', dest='name') @manager.option('-u', '--url', dest='url') def cmd(name, url): """ 自定义命令 执行: python manage.py cmd -n wupeiqi -u http://www.oldboyedu.com 执行: python manage.py cmd --name wupeiqi --url http://www.oldboyedu.com :param name: :param url: :return: """ print(name, url) if __name__ == '__main__': # app.run() manager.run()
使用》》》》》》》》》》》》》》》》》》
创建数据库表
models.py
#!/usr/bin/env python # -*- coding:utf-8 -*- from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, UniqueConstraint, Index,DateTime,ForeignKey from s8day130_pro import db #这里直接继承的就是db.Model 这里实际上是继承了另一个类 此类是用于创建表的 见上文 class Users(db.Model): __tablename__ = 'users' id = Column(Integer, primary_key=True,autoincrement=True) name = Column(String(32),nullable=False,unique=True)
查询数据
accoun.py
from flask import blueprints from s8day130_pro import models from s8day130_pro import db ac = blueprints.Blueprint('ac',__name__) @ac.route('/login',methods=['GET','POST']) def login(): data = db.session.query(models.Users).all() print(data) db.session.remove() return 'Login'
创建离线脚本
drop_db.py
""" Web运行时,flask程序运行起来,用户通过浏览器访问 离线脚本,自定义的一个py文件+使用flask中定义好的功能 """ from s8day130_pro import db from s8day130_pro import create_app from s8day130_pro import models app = create_app() with app.app_context(): # db.drop_all() # db.create_all() data = db.session.query(models.Users).all() print(data)

浙公网安备 33010602011771号