Flask-SQLAlchemy 和离线脚本 和 scoped_session

SQLAlchemy

 

 知识补充   在引入 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
View Code

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
View Code

 

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
View Code

 

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()
View Code

使用》》》》》》》》》》》》》》》》》》

创建数据库表

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)

 

 

 

 

 

 

posted on 2018-05-07 22:52  王大拿  阅读(1034)  评论(0)    收藏  举报

导航