2.8.4SQLAlchemy

总目录:https://blog.csdn.net/qq_41106844/article/details/105553392

Python-后端 - 子目录:https://blog.csdn.net/qq_41106844/article/details/105553324

 

 

武沛齐的sqlalchemy:https://www.cnblogs.com/wupeiqi/articles/8259356.html

官方文档:https://www.osgeo.cn/sqlalchemy/

SQLAlchemy

    ORM(关系映射)框架

        类对应数据库的表

        对象对应数据库的行

    作用:帮助我们使用类和对象快速实现数据库操作

 

操作数据库的库

      -原生:

        PyMySql(支持Python3和Python2)

        MySqlDB(不支持Python3)

      -ORM框架:

        SQLAlchemy

 

使用

创建引擎

        engine = create_engine(

            "mysql+pymysql://root:123456@127.0.0.1:3306/python_ech?charsct=utf8",

            max_overflow = 0,  //超过连接池大小外最多创建的连接

            pool_size = 5,    //连接池大小

            pool_timeout = 30, //线程最多等待时间

            pool_recycle = 1  //多久后进行回收(-1不回收)

        )

设置映射

Base = declarative_base()

class Users(Base):

    __tablename__ = 'users'

    id = Column(Integer,primary_key=True)

    name = Column(String(32),index=True,nullable=False)

    age = Column(Integer,index=True,nullable=False)

    banji = Column(Integer,index=True,nullable=False)

启动

Base.metadata.create_all(engine)     //新建

Base.metadata.drop(engine)             //删除

增删改查

创建连接

SessionFactory = sessionmaker(bind = engine)

session = SessionFactory()

obj1 = Users(name="赵谦")

obj2 = Users(name="孙莉")

 

session.add(obj1)

session.add(obj2)  //插入一个对象

 

session.add_all([

Users(name="赵谦"),

Users(name="孙莉")

])            //插入多个对象

 

session.commit()      //执行

session.close()    //关闭连接

result = session.query(Users).all()  //取出Users表内所有的数据

for row in result:

    print(row.id,row.name,row.age) //遍历显示

 

result1 = session.query(Users).filter(Users.id>3)  //取出Users表内id大于3的数据

for row in result:

    print(row.id,row.name,row.age) //遍历显示

 

result1 = session.query(Users).filter(Users.id>3).first()  //取出Users表内id大于3中的第一条数据

print(result.id,result.name,result.age)

session.query(Users).filter(Users.id < 3).delete()  //将id小于3的全部删除

session.commit()

session.query(Users).filter(Users.id == 3).updata({Users.name:"周武",Users.age:27}) //将id等于3的name改为周武,age改为27

session.query(Users).filter(Users.id == 3).updata({'name':Users.name+"郑旺"},syschronize_session=False)

session.commit()

-常用操作

1.实例化数据(可以使用索引)

result = session.query(Users.id,Users.name,Users.age).all() 

for item in result:

    print(item[0],item.id,item.name)

2.label别名

result = session.query(Users.id,Users.name.label('xm'),Users.age).all() 

3.查看SQL语句

result = session.query(Users.id,Users.name,Users.age)

print(result)

4.查询默认条件是and

session.query(Users).filter(Users.id > 1,Users.name == '王五').all() 

5.between用于限制范围

session.query(Users).filter(Users.id.between(1,3),Users.name == '王五').all()  

6.in_用于限制范围  in可以是另一条语句  ~Users.id.in_([1,3,4])则为not

session.query(Users).filter(Users.id.in_([1,3,4]),Users.name == '王五').all()    

7.使用in_实现子查询

session.query(Users).filter(Users.id.in_(session.query(Users.id).filter(Users.name != "李四")),Users.name == '王五').all()  

8.or_操作符

session.filter(or_(Users.id>3,Users.name == "张三")).all()

9. filter_by传递的是参数,其他与filter相同

 session.query(Users).filter_by(name = "张三").all() 

10.通配符的使用  %:若干各字符  _:一个字符

session.query(Users).filter(User.name.like('张%')).all() 

11.切片

session.query(Users)[1:3]  

12. 降序排序   asc升序   User.age.desc(),User.id.desc()先按照age排序,若age相同,按照id排序

session.query(Users).order_by(User.age.desc()).all()  

13. 分组  可以使用func聚合条件

session.query(Users).group_by(User.banji).all() 

14.使用func聚合条件

session.query(func.max(Users.id)).group_by(User.banji).all()  

15.组合

q1.union(q2).all()  q1.union_all(q2).all()  

上面是我第一次学习时的笔记。

下面开始说这次复习:

安装

语法

python -m pip install sqlalchemy

连接数据库

from sqlalchemy import create_engine

 

#数据库类型+数据库引擎://用户名:密码@IP地址:端口号/数据库名?charset=使用的编码

engine=create_engine('mysql+pymysql://root: @127.0.0.1:3306/sql_py?charset=utf8')

print(engine)

Engine(mysql+pymysql://root:***@127.0.0.1:3306/sql_py?charset=utf8)

 
20155953-805de9a53c6fc154.png
 

 

建表

from sqlalchemy import create_engine

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column,String,Integer

#数据库类型+数据库引擎://用户名:密码@IP地址:端口号/数据库名?charset=使用的编码

engine=create_engine('mysql+pymysql://root: @127.0.0.1:3306/sql_py?charset=utf8')

 

#生成orm基类

Base = declarative_base() 

 

#继承生成的orm基类

class Student(Base):

    __tablename__ ="student"                             #表名

    id = Column(Integer,primary_key=True)        #int类型,设置主键

    name = Column(String(32))                            #字符串类型,32位长度

    banji = Column(String(32))

 

#创建表

Base.metadata.create_all(engine)

 

 
20155953-8d983ca267b4861c.png
 
 
20155953-60024bc598602854.png
 

 

插入数据

from sqlalchemy import create_engine

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column,String,Integer

from sqlalchemy.orm import sessionmaker

 

#数据库类型+数据库引擎://用户名:密码@IP地址:端口号/数据库名?charset=使用的编码

engine=create_engine('mysql+pymysql://root: @127.0.0.1:3306/sql_py?charset=utf8')

#生成orm基类

Base = declarative_base()

 

class Student(Base):#继承生成的orm基类

    __tablename__ ="student"            #表名

    id = Column(Integer,primary_key=True)#int类型,设置主键

    name = Column(String(32))#字符串类型,32位长度

    banji = Column(String(32))

 

#创建与数据库的会话,Session_Class为一个类

Session_Class = sessionmaker(bind=engine)

#实例化与数据库的会话

Session = Session_Class()

 

#插入一行数据

t1=Student(name="小明",banji="三班")

Session.add(t1)

 

#插入多行数据

Session.add_all([

Student(name="小红",banji="二班"),

    Student(name="小刚",banji="一班")

])

 

#必须要提交

Session.commit()

#关闭连接

Session.close()

 
20155953-43b9d20e875c08ae.png
 
 
20155953-0c3a9c1363bad75d.png
 

 

为了更好的进行下面的操作,在数据库中插入了二十条数据。

查询数据 

普通查询

from sqlalchemy import create_engine

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column,String,Integer

from sqlalchemy.orm import sessionmaker

 

#数据库类型+数据库引擎://用户名:密码@IP地址:端口号/数据库名?charset=使用的编码

engine=create_engine('mysql+pymysql://root: @127.0.0.1:3306/sql_py?charset=utf8')

 

#生成orm基类

Base = declarative_base()

class Student(Base):#继承生成的orm基类

    __tablename__ ="student"            #表名

    id = Column(Integer,primary_key=True)#int类型,设置主键

    name = Column(String(32))#字符串类型,32位长度

    banji = Column(String(32))

 

#创建与数据库的会话,Session_Class为一个类

Session_Class = sessionmaker(bind=engine)

#实例化与数据库的会话

Session = Session_Class()

 

#取出Student表内所有的数据

result = Session.query(Student).all()

for rowin result:

    print(row.id, row.name, row.banji)

 

#关闭连接

Session.close()

 
20155953-0dadf01a3f8ac496.png
 
 
20155953-19d63bb06f31f86e.png
运行结果

条件查询(filter)

#取出Student表中id大于15的记录

result = Session.query(Student).filter(Student.id >=15)

for rowin result:

    print(row.id, row.name, row.banji)

 
20155953-b0b04c885afb9b18.png
 
 
20155953-e80285b80146479a.png
运行结果

first()

如果只想要第一条数据就可以用first()。

#取出Student表中id大于15的记录中的第一条

result = Session.query(Student).filter(Student.id >=15).first()

print(result.id,result.name,result.banji)

 
20155953-a01962d5fde8542e.png
 
 
20155953-6fae41be0c4c3469.png
运行结果

 

排序查询

#取出Student表中数据,按照banji降序排序 默认升序排序

result = Session.query(Student).order_by(Student.banji.desc()).all()

for rowin result:

    print(row.id, row.name, row.banji)

 

 
20155953-8a3bc769700a3473.png
 
 
20155953-63bd630b1f290141.png
运行结果

双排序

#取出Student表中数据,外部按照banji降序排序,内部按照id升序排序

result = Session.query(Student).order_by(Student.banji.desc(),Student.id).all()

for rowin result:

    print(row.id, row.name, row.banji)

 
20155953-d2af2552bac34a55.png
 
 
20155953-91e4c35256ab0b26.png
运行结果

分组查询

#取出Student表中数据,按照banji分组。

result = Session.query(Student).group_by(Student.banji).all()

for rowin result:

    print(row.id, row.name, row.banji)

 
20155953-fa867398e0c87249.png
 
 
20155953-4aebf5003823d736.png
运行结果

分组查询一般都是结合聚合函数。

注 需要导入func函数   

from sqlalchemy.sql import func

#取出Student表中数据,按照banji分组,查询每班有多少人。

result = Session.query(func.count(Student.id)).group_by(Student.banji).all()

for rowin result:

    print(row)

 
20155953-00fd873c5b4fa9fd.png
 

运行结果是元组类型

 
20155953-1503b2716927918f.png
运行结果

分组查询当然有分组条件了

#取出Student表中数据,按照banji分组,查询班级人数是偶数的班级人数。

result = Session.query(func.count(Student.id)).group_by(Student.banji).having(func.count(Student.id)%2 ==0).all()  

for rowin result:

    print(row)

 
20155953-0262eef790b33646.png
 
 
20155953-143dd8b2ce2d0e4b.png
运行结果

 

删除数据

删除数据建立在查询数据之上,查询出来数据,删除。

from sqlalchemy import create_engine

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column,String,Integer

from sqlalchemy.orm import sessionmaker

 

#数据库类型+数据库引擎://用户名:密码@IP地址:端口号/数据库名?charset=使用的编码

engine=create_engine('mysql+pymysql://root: @127.0.0.1:3306/sql_py?charset=utf8')

 

#生成orm基类

Base = declarative_base()

class Student(Base):#继承生成的orm基类

    __tablename__ ="student"            #表名

    id = Column(Integer,primary_key=True)#int类型,设置主键

    name = Column(String(32))#字符串类型,32位长度

    banji = Column(String(32))

 

#创建与数据库的会话,Session_Class为一个类

Session_Class = sessionmaker(bind=engine)

#实例化与数据库的会话

Session = Session_Class()

 

#删除id大于15的信息

result = Session.query(Student).filter(Student.id >=15).delete()

#提交修改

Session.commit()

#关闭连接

Session.close()

 
20155953-fc8ac8121af7c34d.png
 
 
20155953-1a6cc9a35d69dee9.png
运行结果

 

修改数据

#一些常见的修改操作

Session.query(Student).filter(Student.id ==1).update({Student.banji:'五班'})

Session.query(Student).filter(Student.id ==2).update({'name':'王红'})

Session.query(Student).filter(Student.id ==3).update({'name':Student.name+"(尖子生)"},synchronize_session=False)

synchronize_session用于query在进行delete or update操作时,对session的同步策略。

也就是修改是否要在当前session中生效。

 
20155953-25f014c9d69ba16e.png
 
 
20155953-e1e7882aee636939.png
运行结果

 

事务

 
20155953-232cd3d1520ae005.png
 

实例:郑旺要和冯晨换班。

#换班

try:

    Session.query(Student).filter(Student.id ==7).update({Student.banji:'二班'})

    raise Exception  #在这里抛出错误  让操作中断

    Session.query(Student).filter(Student.id ==8).update({Student.banji:'三班'})

    Session.commit()

except Exception as e:

    #收到错误,回滚,结束事务。

    Session.rollback()

    Session.commit()

 
20155953-02c074ce0ed1cd8b.png
 
 
20155953-76757d10c76357a4.png
换班失败

 

其他常用操作

别名

#label 设置别名

result = Session.query(Student.id.label("学号")).filter(Student.id <=5)

for i in result:

    print(i.学号)

 
20155953-ea1149478e281643.png
 
 
20155953-20aba855c0c7474a.png
运行结果

 

查看SQL语句

#查看sql语句

result = Session.query(Student.id.label("学号")).filter(Student.id <=5)

print(result)

 
20155953-4edbb98418a55258.png
 
 
20155953-a917c738a9e782b1.png
运行结果

 

操作符

操作符有  in_  和 ~in_  两种

#使用in_ 操作符 找到符合的id

result = Session.query(Student).filter(Student.id.in_([1,3,4,5])).all()

for i in result:

    print(i.id,i.name,i.banji)

 
20155953-7d27329dbd220a8a.png
 
 
20155953-64a7e2545f17d9d3.png
运行结果

#~in_ 会输出和 in_ 相反的结果

result = Session.query(Student).filter(~Student.id.in_([1,3,4,5])).all()

for i in result:

    print(i.id,i.name,i.banji)

 
20155953-1b8573fd51689f28.png
 
 
20155953-192949d3032bc809.png
运行结果

 

逻辑运算符(and_ in or_)

不适用的逻辑运算符:

print("----------普通查询----------")

#普通查询

result = Session.query(Student).filter(Student.banji =='一班',Student.id >=8).all()

for i in result:

    print(i.id,i.name,i.banji)

 
20155953-2f8fb673da280fd3.png
 
 
20155953-b0705fe4f0e6436c.png
运行结果

使用逻辑运算符:

from sqlalchemy import and_, or_

 

print("----------and_----------")

#使用and_

result = Session.query(Student).filter(and_(Student.banji =='一班',Student.id >=8)).all()

for i in result:

    print(i.id,i.name,i.banji)

 

print("----------or_----------")

#使用or_

result = Session.query(Student).filter(or_(Student.banji =='一班',Student.id >=8)).all()

for i in result:

    print(i.id,i.name,i.banji)

 

print("----------or_(and_)----------")

#and_  和 or_  可以嵌套使用  也可以并行使用

result = Session.query(Student).filter(

    or_(

        Student.banji =='一班',

        and_(Student.id >=8,Student.id <=12)

    )

).all()

for i in result:

    print(i.id,i.name,i.banji)

 
20155953-e2580bd9cdae037c.png
 
 
20155953-435b44939a89de9c.png
运行结果

通配符

#使用通配符

result = Session.query(Student).filter(Student.name.like('小%')).all()

for i in result:

    print(i.id,i.name,i.banji)

 

print("----------使用反向通配符---------")

#同样也有反向的

result = Session.query(Student).filter(~Student.name.like('小%')).all()

for i in result:

        print(i.id,i.name,i.banji)

 
20155953-296761c275aae5e9.png
 
 
20155953-5f9e9ca40bd737ff.png
运行结果

联合查询

Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;

union_all:对两个结果集进行并集操作,包括重复行,不进行排序;

 
20155953-61738d4415b43607.png
 

我们建立另一个表

s1 = Session.query(Student.name).filter(Student.id >=1)

s2 = Session.query(Student1.name).filter(Student1.id >=1)

result=s1.union(s2).all()

for iin result:

    print(i.name)

 

print("---")

 

s1 = Session.query(Student.name).filter(Student.id >=1)

s2 = Session.query(Student1.name).filter(Student1.id >=1)

result=s1.union_all(s2).all()

for iin result:

    print(i.name)

 
20155953-69cc7a8df2a3f4e5.png
 
 
20155953-1a895e9f086e0027.png
union运行结果
 
20155953-c1f12275ed011e51.png
union_all运行结果
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒 暄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值