2.8.4SQLAlchemy

总目录:https://www.jianshu.com/p/e406a9bc93a9

Python-后端 - 子目录:https://www.jianshu.com/p/29d6539d6554

武沛齐的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:[email protected]: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)


建表

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)



插入数据

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


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

查询数据 

普通查询

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

运行结果

条件查询(filter)

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

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

for rowin result:

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

运行结果

first()

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

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

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

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

运行结果


排序查询

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

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

for rowin result:

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


运行结果

双排序

#取出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)

运行结果

分组查询

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

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

for rowin result:

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

运行结果

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

注 需要导入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)

运行结果是元组类型

运行结果

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

#取出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)

运行结果


删除数据

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

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

运行结果


修改数据

#一些常见的修改操作

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中生效。

运行结果


事务

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

#换班

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

换班失败


其他常用操作

别名

#label 设置别名

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

for i in result:

    print(i.学号)

运行结果


查看SQL语句

#查看sql语句

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

print(result)

运行结果


操作符

操作符有  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)

运行结果

#~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)

运行结果


逻辑运算符(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)

运行结果

使用逻辑运算符:

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)

运行结果

通配符

#使用通配符

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)

运行结果

联合查询

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

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

我们建立另一个表

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)

union运行结果
union_all运行结果

你可能感兴趣的:(2.8.4SQLAlchemy)