flask-sqlalchemy(包含离线脚本,with在上下文管理的应用)

flask-sqlalchemy(包含离线脚本,with在上下文管理的应用)

 

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

- 创建表
class User(db.Model):
pass

- 操作表
db.session

具体使用

项目目录结构

步骤:

复制代码
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:[email protected]:
        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,
        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()
            return 'Login'
复制代码

__init__文件

复制代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# 包含了SQLAlchemy相关的所有操作
db = SQLAlchemy()

from .views.account import ac
from .views.home import hm

def create_app():
    app = Flask(__name__)
    app.config.from_object('settings.DevelopmentConfig')

    app.register_blueprint(ac)
    app.register_blueprint(hm)

    db.init_app(app)

    return app
复制代码

在配置完成后,我们也写了models表后,如果进行数据迁移(在数据库中创建表),我们可以使用离线脚本(不需要运行项目,可以直接执行的文件)

复制代码
"""
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)
复制代码

db就我们在__init__文件中实例化的对象,它包含了create_all(创建表)和drop_all(删除表)的命令,但是由于在使用db时我们需要用到app中关于数据库的配置(从上下文中取),但是这时项目没有运行,没有请求,在local类中没有app的内容,所以我们使用with

方法,利用上下文管理,将需要的内容添加到loacl对象中

with方法

复制代码
class Sxw(object):
    def __enter__(self):
        '''进入'''
        print("你好啊")

    def __exit__(self, exc_type, exc_val, exc_tb):
        '''退出'''
        print("hao")

obj = Sxw()
with obj:
    print("正在执行")
复制代码

打印结果截图

在上面的离线脚本中,进入时其实就是在__enter__中执行了push方法,将appcontext的对象放入到local中,而退出时则是在__exit__中执行了pop方法,将对象从local中删除

SQLAlchemy两种创建session的方式

复制代码
方式一:
    import models
    from threading import Thread
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import create_engine

    engine =create_engine("mysql+pymysql://root:[email protected]:3306/s8day128db?charset=utf8",pool_size=2,max_overflow=0)
    XXXXXX = sessionmaker(bind=engine)

    def task():
        from sqlalchemy.orm.session import Session
        session = XXXXXX()

        data = session.query(models.Classes).all()
        print(data)

        session.close()

    for i in range(10):
        t = Thread(target=task)
        t.start()

方式二(推荐):
    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:[email protected]:3306/s8day128db?charset=utf8",pool_size=2,max_overflow=0)
    XXXXXX = sessionmaker(bind=engine)

    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()
复制代码

方式二的内部其实就利用threading.loacl为每个线程单独创建了一个session

flask-session默认也是使用的第二种方式:scoped_session

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

- 创建表
class User(db.Model):
pass

- 操作表
db.session

具体使用

项目目录结构

步骤:

复制代码
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:[email protected]:
        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,
        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()
            return 'Login'
复制代码

__init__文件

复制代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# 包含了SQLAlchemy相关的所有操作
db = SQLAlchemy()

from .views.account import ac
from .views.home import hm

def create_app():
    app = Flask(__name__)
    app.config.from_object('settings.DevelopmentConfig')

    app.register_blueprint(ac)
    app.register_blueprint(hm)

    db.init_app(app)

    return app
复制代码

在配置完成后,我们也写了models表后,如果进行数据迁移(在数据库中创建表),我们可以使用离线脚本(不需要运行项目,可以直接执行的文件)

复制代码
"""
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)
复制代码

db就我们在__init__文件中实例化的对象,它包含了create_all(创建表)和drop_all(删除表)的命令,但是由于在使用db时我们需要用到app中关于数据库的配置(从上下文中取),但是这时项目没有运行,没有请求,在local类中没有app的内容,所以我们使用with

方法,利用上下文管理,将需要的内容添加到loacl对象中

with方法

复制代码
class Sxw(object):
    def __enter__(self):
        '''进入'''
        print("你好啊")

    def __exit__(self, exc_type, exc_val, exc_tb):
        '''退出'''
        print("hao")

obj = Sxw()
with obj:
    print("正在执行")
复制代码

打印结果截图

在上面的离线脚本中,进入时其实就是在__enter__中执行了push方法,将appcontext的对象放入到local中,而退出时则是在__exit__中执行了pop方法,将对象从local中删除

SQLAlchemy两种创建session的方式

复制代码
方式一:
    import models
    from threading import Thread
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import create_engine

    engine =create_engine("mysql+pymysql://root:[email protected]:3306/s8day128db?charset=utf8",pool_size=2,max_overflow=0)
    XXXXXX = sessionmaker(bind=engine)

    def task():
        from sqlalchemy.orm.session import Session
        session = XXXXXX()

        data = session.query(models.Classes).all()
        print(data)

        session.close()

    for i in range(10):
        t = Thread(target=task)
        t.start()

方式二(推荐):
    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:[email protected]:3306/s8day128db?charset=utf8",pool_size=2,max_overflow=0)
    XXXXXX = sessionmaker(bind=engine)

    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()
复制代码

方式二的内部其实就利用threading.loacl为每个线程单独创建了一个session

flask-session默认也是使用的第二种方式:scoped_session

猜你喜欢

转载自www.cnblogs.com/xyhh/p/10860411.html