欢迎来到夜的世界

莫听穿林打叶声,何妨吟啸且徐行。竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生.料峭春风吹酒醒,微冷,山头斜照却相迎。回首向来萧瑟处,归去,也无风雨也无晴。
扩大
缩小

SQLAlchemy

       一 . 介绍       

   SQLAlchemy 是一个基于 python 实现的 ORM 框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简而言之就是: 将类和对象转换成SQL,然后使用数据API进行SQL并获取执行结果.

 pip install sqlalchemy -i http://pypi.douban.com/simple  --trusted-host pypi.douban.com 

# 下载SQLAlchemy 模块

 

 

组成部分:

  • Engine,框架的引擎
  • Connection Pooling ,数据库连接池
  • Dialect,选择连接数据库的DB API种类
  • Schema/Types,架构和类型
  • SQL Exprression Language,SQL表达式语言

SQLAlchemy本身无法操作数据库,其必须以来pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:

MySQL-Python
    mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
    
pymysql
    mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
    
MySQL-Connector
    mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
    
cx_Oracle
    oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
    
更多:http://docs.sqlalchemy.org/en/latest/dialects/index.html

 

 

       二 . 使用       

    1 . 创建数据表   

   注意 : 要先创建对应的数据库,我的数据库叫 s1

 # ORM中的数据表是什么呢?
 # Object Relation Mapping
 # Object - Table 通过 Object 去操纵数据表
 # 从而引出了我们的第一步创建数据表 - 创建Object
 # 1. 创建Object
 # class User(object):
 #     pass



#  通过SQLAlchemy创建数据表
#  1.导入SQLAlchemy

from sqlalchemy.ext.declarative import declarative_base

#  2.创建ORM模型基类,要被继承
Base = declarative_base()

#  3.导入ORM对应数据库类型的字段,比如:列,整型,字符串
from sqlalchemy import Column, Integer, String


#  4.创建ORM对象
# 当前的这个Object继承了Base也就是代表了Object继承了ORM的模型
class User(Base):   # 相当于 Django Models中的 Model
       # 创建表名,__双下划线
    __tablename__ = "user"
    #  设置为主键,并且自增(默认)
    # id = Column(数据类型,索引,主键,外键,等等)
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 设置索引
    name = Column(String(32), index=True)


#  5.创建数据库连接
from sqlalchemy import create_engine

# 数据库创建连接完成
# 连接时 用mysql 和 python 的pymsql
enginne = create_engine("mysql+pymysql://root:@127.0.0.1:3306/s1?charset=utf8")

#  6.去数据库中创建于User所对应的数据表
#  去User数据库中创建所有基层Base类的 ORM对象
# Base 自动检索所有继承Base的ORM 对象 并且创建所有的数据表
Base.metadata.create_all(enginne)

 


      2 . 增删改查操作    

  注意 : 在增删改查的操作中,除了查询不用 commit之外,增/删/改  都需要

#执行会话的操作
db_session.commit()
#关闭会话
db_session.close()

 2.1 增加数据

# 创建会话 -- 打开数据库连接
from create_table import enginne
from sqlalchemy.orm import sessionmaker
# 创建会话窗口
# 创建 sessionmaker 会话对象,将数据库引擎 engine 交给 sessionmaker
Session = sessionmaker(enginne)
# 打开会话窗口
db_session = Session()

#  1.增加数据   == insert
#  原生mysql语句 , insert into user(name) values("yirenye")
from create_table import User
user_obj = User(name="异人夜")
# 通过de_session已经打开的会话窗口,提交数据
db_session.add(user_obj)  # 相当于 insert into
# 执行会话窗口中的所有操作
db_session.commit()
# 关闭窗口
db_session.close()

# 2.增加批量数据 -- 多条
from create_table import User
db_session.add_all([
    User(name="小慯"),
    User(name="Tom"),
    User(name="Ealse"),
])
db_session.commit()
db_session.close()

# 扩展
from create_table import User
User1 = User(name="666")
User2 = User(name="888")
User3 = User(name="999")

db_session.add(User1)
db_session.add(User2)
db_session.add(User3)

db_session.commit()
db_session.close()
增加数据

 

2.2 查询书籍

# 会话窗口
from sqlalchemy.orm import sessionmaker
from create_table import enginne

Session = sessionmaker(enginne)
db_session = Session()

from create_table import User

# 1.简单查询
#  原生sql语句  select * from table
# 查询全部
user_list = db_session.query(User).all()
for row in user_list:
    print(row.id, row.name)
"""
5 666
6 888
7 999
4 Ealse
3 Tom
2 小慯
1 异人夜
"""
# 查询一条
user = db_session.query(User).first()
print(user.id, user.name)
# 5 666

# 2.带条件查询
user_list = db_session.query(User).filter(User.id == 4).all()
print(user_list[0].id, user_list[0].name)
# 4 Ealse

user = db_session.query(User).filter_by(id=3).first()
print(user.id, user.name)
# 3 Tom

user_list = db_session.query(User).filter(User.id >= 4).all()
for row in user_list:
    print(row.id, row.name)
"""
4 Ealse
5 666
6 888
7 999
"""

# 扩展,查看sql语句
sql = db_session.query(User).filter(User.id >= 5)
print(sql)
"""
SELECT user.id AS user_id, user.name AS user_name 
FROM user 
WHERE user.id >= %(id_1)s
"""
# 关闭会话
db_session.close()
查询数据

2.3 修改数据 

# 更新修改数据
from sqlalchemy.orm import sessionmaker
from create_table import enginne, User

Session = sessionmaker(enginne)
db_session = Session()

# 修改数据 -- 先查询数据在进行修改
#  原生sql语句的修改(将id=1的数据的 name 修改成666) : update "user" set "name" = "666" where id = 1
res = db_session.query(User).filter(User.name=="Ealse").update({"name":"杰斯"})
print(res)
# 1  -- 符合条件的只有一条
db_session.commit()
db_session.close()

res = db_session.query(User).filter(User.id >= 5).update({"name":666666})
print(res)
# 3  -- 符合条件的有3条
db_session.commit()
db_session.close()
修改数据

 

2.4 删除数据 

# 删除数据
# 导入 ORM 创建会话
from sqlalchemy.orm import sessionmaker
from create_table import enginne, User

Session = sessionmaker(enginne)
db_session = Session()

# 删除也是先查询--在删除
# sql原生语句删除 :  delete from user where id=5
#  1.删除一个
res = db_session.query(User).filter(User.id == 5).delete()
print(res)
# 1  -- 符合条件的只有一条
db_session.commit()
db_session.close()

# 2.删除多条数据
res = db_session.query(User).filter(User.name == "666666").delete()
print(res)
# 2  -- 符合条件的有2条
db_session.commit()
db_session.close()
删除数据

2.5 . 高级版查询操作 

 

# 高级版查询操作,厉害了哦
# 老规矩
from create_table import User, enginne
from sqlalchemy.orm import sessionmaker

Session = sessionmaker(enginne)
db_session = Session()

# 1.查询表操作
#  and  or 的用法,在SQLAlchemy 中,要用SQLAlchemy 的and 和 or
# from sqlalchemy.sql import and_, or_

ret = db_session.query(User).filter(and_(User.id == 4,User.name == "Tom")).all()
print(ret)
#  [] ,因为id=4的name!=Tom,所有会查询不到

ret1 = db_session.query(User).filter(or_(User.id == 4,User.name == "Tom")).all()
print(ret1)
# [<create_table.User object at 0x000002451F90FE80>, <create_table.User object at 0x000002451F938048>] 查询出来2条记录

#  2.查询所有
ret2 = db_session.query(User).all()

#  3.查询数据,指定查询数据列,加入别名
ret3 = db_session.query(User.id.label("uid"),User.name.label("username")).first()
print(ret3.uid, ret3.username)
# 3 Tom , 在查询first的时候,会找在数据库中的第一个,可能不是id=1的

#  4.表达式筛选条件
ret4 = db_session.query(User).filter(User.name == "Tom").all()
print(ret4)
# [<create_table.User object at 0x00000278BBBBFF98>]

#  5.元素sql筛选条件
ret5 = db_session.query(User).filter_by(name="Tom").all()
print(ret5)
# [<create_table.User object at 0x000001EDB192F470>]

ret52 = db_session.query(User).filter_by(name="Tom").first()
print(ret52)
# <create_table.User object at 0x000001EDB192F470>

#  6.字符串匹配方式筛选条件,并进行 order_by 进行排序
from sqlalchemy.sql import text

ret6 = db_session.query(User).filter(text("id<:value")).params(value=3).order_by(User.id).all()
print(ret6)
# [<create_table.User object at 0x0000018C4BA2FF98>, <create_table.User object at 0x0000018C4BA2F828>]

#  7.原生SQL查询
ret7 = db_session.query(User).from_statement(text("SELECT * FROM User where name=:name")).params(name='DragonFire').all()

#  8.筛选查询列
# query的时候我们不在使用User ORM对象,而是使用User.name来对内容进行选取
user_list8 = db_session.query(User.name).all()
print(user_list8)
# [('Tom',), ('小慯',), ('异人夜',), ('杰斯',)]
for row in user_list8:
    print(row.name)
"""
Tom
小慯
异人夜
杰斯
"""

#  9.别名映射  name as nick
user_list9 = db_session.query(User.name.label("nick")).all()
print(user_list9)
for row in user_list9:
    print(row.nick)
# 这里要写别名了

#  10.排序 :
# 正序,默认
user_list10 = db_session.query(User).order_by(User.id.asc()).all()
# 反序
user_list11 = db_session.query(User).order_by(User.id.desc()).all()
for row in user_list11:
    print(row.name,row.id)

#  11.
ret12 = db_session.query(User).filter(User.id.between(1,3)).all()
print(ret12)
# between 大于等于1 小于等于3的
# [<create_table.User object at 0x000002687461F080>, <create_table.User object at 0x000002687461F0B8>, <create_table.User object at 0x000002687461FE80>]
ret13 = db_session.query(User).filter(User.id.in_([1,4])).all() # in_([1,3,4])
# 只查询id等于1,3,4的
ret14 = db_session.query(User).filter(~User.id.in_([1,2,3])).all() # ~xxxx.in_([1,3,4])
# 查询不等于1,3,4的

#   12.and_ , or_ 的其他用法
# 查询条件中符合其中一条就可以
from sqlalchemy.sql import and_, or_
ret15 = db_session.query(User).filter(
    or_(
        User.id < 2,
        and_(User.name == "Tom",User.id > 2),
        User.name != ""
    )
)
print(ret15)
"""
SELECT user.id AS user_id, user.name AS user_name 
FROM user 
WHERE user.id < %(id_1)s OR user.name = %(name_1)s AND user.id > %(id_2)s OR user.name != %(name_2)s
"""

#   13.其他查询条件
"""
ret = session.query(User).filter_by(name='DragonFire').all()
ret = session.query(User).filter(User.id > 1, User.name == 'DragonFire').all()
ret = session.query(User).filter(User.id.between(1, 3), User.name == 'DragonFire').all() # between 大于1小于3的
ret = session.query(User).filter(User.id.in_([1,3,4])).all() # in_([1,3,4]) 只查询id等于1,3,4的
ret = session.query(User).filter(~User.id.in_([1,3,4])).all() # ~xxxx.in_([1,3,4]) 查询不等于1,3,4的
ret = session.query(User).filter(User.id.in_(session.query(User.id).filter_by(name='DragonFire'))).all() 子查询
from sqlalchemy import and_, or_
ret = session.query(User).filter(and_(User.id > 3, User.name == 'DragonFire')).all()
ret = session.query(User).filter(or_(User.id < 2, User.name == 'DragonFire')).all()
ret = session.query(User).filter(
    or_(
        User.id < 2,
        and_(User.name == 'eric', User.id > 3),
        User.extra != ""
    )).all()
# select * from User where id<2 or (name="eric" and id>3) or extra != "" 

# 通配符
ret = db_session.query(User).filter(User.name.like('e%')).all()
ret = db_session.query(User).filter(~User.name.like('e%')).all()

# 限制
ret = db_session.query(User)[1:2]

# 排序
ret = db_session.query(User).order_by(User.name.desc()).all()
ret = db_session.query(User).order_by(User.name.desc(), User.id.asc()).all()

# 分组
from sqlalchemy.sql import func

ret = db_session.query(User).group_by(User.extra).all()
ret = db_session.query(
    func.max(User.id),
    func.sum(User.id),
    func.min(User.id)).group_by(User.name).all()

ret = db_session.query(
    func.max(User.id),
    func.sum(User.id),
    func.min(User.id)).group_by(User.name).having(func.min(User.id) >2).all()
"""
高级查询

2.6 . 高级版修改操作 

   未修改的数据 :                                                           

# 高级版更新操作
from create_table import User, enginne
from sqlalchemy.orm import sessionmaker

Session = sessionmaker(enginne)
db_session = Session()

#  1.直接修改
ret = db_session.query(User).filter(User.id > 0).update({"name":"异人夜真帅"})

#  2.在原有值基础上添加 - 1+
#  synchronize_session 是否提交完之后再跟新,有可能会前面有提交的东西会发生覆盖现象
ret2 = db_session.query(User).filter(User.id > 0).update({User.name:User.name + "天才"},synchronize_session=False)

#  3.在原有值基础上添加 - 2
db_session.query(User).filter(User.id > 0).update({"age": User.age + 1}, synchronize_session="evaluate")
db_session.commit()
高级修改

   

 

      3 . 一对多操作 : ForeignKey   

3.1 创建数据表及关系 relationship : 

# 一对多建表操作
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship


class Student(Base):
    __tablename__ = "student"
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    school_id = Column(Integer,ForeignKey("school.id"))
    # 正向跨表查询用stu2sch, 反向跨表查询用sch2stu
    stu2sch = relationship("School",backref="sch2stu")


class School(Base):
    __tablename__ = "school"
    id = Column(Integer, primary_key=True)
    name = Column(String(32))


from sqlalchemy import create_engine

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

Base.metadata.create_all(engine)
crud_table_ForeignKey

3.2 基于 relationship 增加数据 :  

# 添加数据
from sqlalchemy.orm import sessionmaker
from create_table_ForeignKey import engine,Student,School

Session = sessionmaker(engine)
db_session = Session()

#  1.添加数据 --笨
# 添加学校
sch_obj = School(name="清华大学")
db_session.add(sch_obj)
db_session.commit()
# 添加学生
sch = db_session.query(School).filter(School.name == "清华大学").first()
stu_obj = Student(name="异人夜",school_id=sch.id)
db_session.add(stu_obj)
db_session.commit()
db_session.close()


#  2.添加数据 -- 正向  relationship 版,学生->学校
stu_obj = Student(name="chuan",stu2sch=School(name="香港大学"))
db_session.add(stu_obj)
db_session.commit()
db_session.close()

# 3.添加数据 - 反向 relationship 版,学校->学生
sch_obj = School(name="厦门大学")
sch_obj.sch2stu = [Student(name="雯雯"),Student(name="lantian")]
db_session.add(sch_obj)
db_session.commit()
db_session.close()
crud_insert_ForeignKey

3.3 基于 relationship  查询数据 :  

# 添加数据
from sqlalchemy.orm import sessionmaker
from create_table_ForeignKey import engine,Student,School

Session = sessionmaker(engine)
db_session = Session()

# 1.查询数据 - relationship 版 正向
stu = db_session.query(Student).all()
for row in stu:
# row.to_class.name 通过Student对象中的关系字段relationship stu2sch获取关联 School中的name
    print(row.id,row.name,row.school_id,row.stu2sch.name)

db_session.close()
"""
1 异人夜 1 清华大学
2 chuan 3 香港大学
3 雯雯 4 厦门大学
4 lantian 4 厦门大学
"""

# 2.查询数据 - relationship 版 反向
sch = db_session.query(School).all()
for school in sch:
    for student in school.sch2stu:
        print(school.id, school.name,student.name)

db_session.close()
"""
1 清华大学 异人夜
3 香港大学 chuan
4 厦门大学 雯雯
4 厦门大学 lantian
"""
crud_select_ForeignKey

3.4 基于 relationship  修改数据 :   

# 添加数据
from sqlalchemy.orm import sessionmaker
from create_table_ForeignKey import engine,Student,School

Session = sessionmaker(engine)
db_session = Session()

# 修改数据
sch = db_session.query(School).filter(School.name=="北京大学").first()
db_session.query(Student).filter(Student.name=="lantian").update({"school_id":sch.id})
db_session.commit()
db_session.close()
crud_update_ForeignKey

3.5 基于 relationship  删除数据 : 

# 删除数据
from sqlalchemy.orm import sessionmaker
from create_table_ForeignKey import engine,Student,School

Session = sessionmaker(engine)
db_session = Session()


sch = db_session.query(School).filter(School.name=="北京大学").first()
db_session.query(Student).filter(Student.school_id == sch.id).delete()
db_session.commit()
db_session.close()
crud_delete_ForeignKey

 

 

       4 . 多对多 : ManyToMany      

4.1 创建表及关系

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship


class Girls(Base):
    __tablename__ = "girl"
    id = Column(Integer, primary_key=True)
    name = Column(String(32))

    # 建立多表之间的关系,girl表与boy表建立关系,通过hotel表
    girl2boy = relationship("Boys", secondary="hotel", backref="boy2girl")


class Boys(Base):
    __tablename__ = "boy"
    id = Column(Integer, primary_key=True)
    name = Column(String(32))


class Hotel(Base):
    __tablename__ = "hotel"
    id = Column(Integer, primary_key=True)
    girl_id = Column(Integer, ForeignKey("girl.id"))
    boy_id = Column(Integer, ForeignKey("boy.id"))


from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/s1?charset=utf8")
Base.metadata.create_all(engine)

4.2.基于 relationship 增加数据 

# 多对多添加数据
from sqlalchemy.orm import sessionmaker
from create_table_manytomany import engine,Boys,Girls,Hotel

Session = sessionmaker(engine)
db_session = Session()

# 1.通过Boy添加Girl和Hotel数据,relationship  - 反向
boy = Boys(name="小明")
boy.boy2girl = [Girls(name="小丽"),Girls(name="小红")]
db_session.add(boy)
db_session.commit()
db_session.close()

# 2.通过Boy添加Girl和Hotel数据,relationship  - 正向
girl_obj = Girls(name="露丝",girl2boy=[Boys(name="小王"),Boys(name="小李")])
db_session.add(girl_obj)
db_session.commit()
db_session.close()
多对多添加

4.3.基于 relationship 查询数据 

# 多对多查询数据
from sqlalchemy.orm import sessionmaker
from create_table_manytomany import engine,Boys,Girls,Hotel

Session = sessionmaker(engine)
db_session = Session()

#  1.查询 relationship  正向
girl_list = db_session.query(Girls).all()
for girl in girl_list:
    for boy in girl.girl2boy:
        print(girl.name,boy.name)
"""
小丽 小明
小红 小明
露丝 小王
露丝 小李
"""

#  2.查询 relationship  反向
boy_list = db_session.query(Boys).all()
for boy in boy_list:
    for girl in boy.boy2girl:
        print(boy.name,girl.name)
"""
小明 小丽
小明 小红
小王 露丝
小李 露丝
"""
多对多查询

 

posted on 2019-02-14 18:04  二十四桥_明月夜  阅读(218)  评论(0编辑  收藏  举报

导航