织梦CMS - 轻松建站从此开始!

罗索

sqlalchemy 执行原生sql语句

jackyhwei 发布于 2022-06-24 14:58 点击:次 
其实返回的session是scoped_session类型对象, 再通过session()才会创建Session对象, 不过scoped_session实现了代理功能, 进行数据操作时, 会自动创建/获取实现了线程隔离的Session对象并执行操作
TAG: SQLAlchemy  

from contextlib import contextmanager
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import relationship, scoped_session
from sqlalchemy.orm import sessionmaker


def create_session(engine):
    """封装Session创建过程   此函数只在应用初始化时调用一次即可"""

    # 创建Session工厂     SessionFactory()就可以创建出session对象, 但是该对象没有实现线程隔离
    SessionFactory = sessionmaker(bind=engine)

    # 生成线程隔离的session对象(每个线程取自己的session)
    session = scoped_session(SessionFactory)
    # ps: 其实返回的session是scoped_session类型对象, 再通过session()才会创建Session对象, 不过scoped_session实现了代理功能, 进行数据操作时, 会自动创建/获取实现了线程隔离的Session对象并执行操作

    return session


# 创建模型基类
Base = declarative_base()

# 创建数据库引擎
# 细节1  sqlalchemy默认实现了连接池功能, 并且可以自动重连(pool_size 连接池中的连接数, max_overflow 超出连接池的额外连接数)
# 细节2  如果数据库使用utf-8支持中文, 则设置连接地址时需要标明  ?charset=utf8   否则报错
engine = create_engine('mysql://root:mysql@127.0.0.1:3306/test27?charset=utf8', echo=False, pool_size=5, max_overflow=10)

# 创建会话
session = create_session(engine)


class User(Base):
    __tablename__ = 't_user'
    id = Column(Integer, primary_key=True)
    name = Column(String(20), unique=True)
    addresses = relationship('Address')


class Address(Base):
    __tablename__ = 't_address'
    id = Column(Integer, primary_key=True)
    detail = Column(String(20))
    user_id = Column(Integer, ForeignKey('t_user.id'))


@contextmanager  # 装饰器形式的上下文管理器
def session_scope():
    """使用上下文管理器对session和事务操作进行封装"""
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.remove()  # session工作完成, 销毁session, 释放内存


def index():
    """模拟视图函数"""

    with session_scope() as session:  # 获取session对象, 代码块执行完会自动提交 并 销毁session
        """增加数据"""
        user1 = User(name='zs')
        session.add(user1)
        session.flush()

        adr1 = Address(detail="中关村3号", user_id=user1.id)
        adr2 = Address(detail="华强北5号", user_id=user1.id)
        session.add_all([adr1, adr2])

        """查询数据"""
        # ret = session.query(User, Address).join(Address, User.id == Address.user_id).filter(User.name == 'zs').all()
        # for user, adr in ret:
        #     print(user.name, adr.detail)


        """执行原生SQL"""
        # data = session.execute('select * from t_user')
        # print(type(data))
        # row = data.fetchone()  # 取第一条
        # print(row.id)  # 取主键
        # print(row.name)  # 取字段

        # rows = data.fetchall()  # 取所有数据
        # for row in rows:
        #     print(row.id, row.name)

        # print(data.rowcount)  # 取条数


if __name__ == '__main__':
    # 删除所有表
    Base.metadata.drop_all(engine)
    # 创建所有表
    Base.metadata.create_all(engine)

    index()

(wjun0)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/202206/17868.html]
本文出处:博客园 作者:wjun0 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
相关文章
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容