• Python操作MySQL:pymysql和SQLAlchemy


    本篇对于Python操作MySQL主要使用两种方式:

    • 原生模块 pymsql
    • ORM框架 SQLAchemy

    pymsql

    pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同。

    下载安装

    pip3 install pymysql
    

    使用操作

    1、执行SQL

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import pymysql
      
    # 创建连接
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
    # 创建游标
    cursor = conn.cursor()
      
    # 执行SQL,并返回收影响行数
    effect_row = cursor.execute("update hosts set host = '1.1.1.2'")
      
    # 执行SQL,并返回受影响行数
    #effect_row = cursor.execute("update hosts set host = '1.1.1.2' where nid > %s", (1,))
      
    # 执行SQL,并返回受影响行数
    #effect_row = cursor.executemany("insert into hosts(host,color_id)values(%s,%s)", [("1.1.1.11",1),("1.1.1.11",2)])
      
      
    # 提交,不然无法保存新建或者修改的数据
    conn.commit()
      
    # 关闭游标
    cursor.close()
    # 关闭连接
    conn.close()
    

    示例:

    import pymysql
    
    
    conn = pymysql.connect(host="10.37.129.3",port=3306,user="egon",passwd="123456",db="homework",charset="utf8")
    
    cursor = conn.cursor()
    
    
    #方式一:
    
    sql = "select * from course where cid=1"
    effect_row = cursor.execute(sql)
    
    
    # 方式二:
    sql = "select * from course where cid='%s'" %(1,)
    effect_row = cursor.execute(sql)
    
    
    # 方式三  普通  列表
    sql = "select * from course where cid='%s'"
    
    effect_row = cursor.execute(sql,1)
    effect_row = cursor.execute(sql,[1])
    
    
    # 方式四  字典格式
    
    sql = "select * from course where cid='%(u)s'"
    effect_row = cursor.execute(sql,{"u":1})
    
    
    row_1 = cursor.fetchone()
    
    cursor.close()
    conn.close()
    
    print(row_1)
    

    2、获取新创建数据自增ID

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import pymysql
      
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
    cursor = conn.cursor()
    cursor.executemany("insert into hosts(host,color_id)values(%s,%s)", [("1.1.1.11",1),("1.1.1.11",2)])
    conn.commit()
    cursor.close()
    conn.close()
      
    # 获取最新自增ID
    new_id = cursor.lastrowid
    

    3、获取查询数据

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import pymysql
      
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
    cursor = conn.cursor()
    cursor.execute("select * from hosts")
      
    # 获取第一行数据
    row_1 = cursor.fetchone()
      
    # 获取前n行数据
    # row_2 = cursor.fetchmany(3)
    # 获取所有数据
    # row_3 = cursor.fetchall()
      
    conn.commit()
    cursor.close()
    conn.close()
    

    注:在fetch数据时按照顺序进行,可以使用cursor.scroll(num,mode)来移动游标位置,如:

    • cursor.scroll(1,mode='relative')  # 相对当前位置移动
    • cursor.scroll(2,mode='absolute') # 相对绝对位置移动

    4、fetch数据类型

      关于默认获取的数据是元祖类型,如果想要或者字典类型的数据,即:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import pymysql
      
    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
      
    # 游标设置为字典类型
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    r = cursor.execute("call p1()")
      
    result = cursor.fetchone()
      
    conn.commit()
    cursor.close()
    conn.close()
    

     5、插入演示

    import pymysql
    
    
    conn = pymysql.connect(host="10.37.129.3",port=3306,user="egon",passwd="123456",db="student_info",charset="utf8")
    
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    
    #插入一行
    # sql = "insert into student_info(sname,gender,class_id) VALUES('alex1','女',2)"
    
    #插入多行
    sql = "insert into student_info(sname,gender,class_id) VALUES('alex1','女',2),('alex2','女',2),('alex3','女',2)"
    
    r = cursor.execute(sql)
    
    #或
    
    sql = "insert into userinfo(username,password) values(%s,%s)"
    # 受影响的行数
    r = cursor.executemany(sql,[('egon','sb'),('laoyao','BS')])
    
    
    
    
    conn.commit()
    cursor.close()
    conn.close()
    
    print(r)
    

    6、补充

    # sql 注入
    import pymysql
    
    user = input("username:")
    pwd = input("password:")
    
    conn = pymysql.connect(host="localhost",user='root',password='',database="db3")   #建立与客户端的链接
    cursor = conn.cursor()
    sql = "select * from userinfo where username='%s' and pwd='%s'" %(user,pwd,) #不要自己定义放置占位符user和pwd,防数据库被泄露
    # select * from userinfo where username='uu' or 1=1 -- ' and password='%s'
    #上面部分会理解成,第一部分:select * from userinfo where username='uu',第二部分:or 1=1,第三部分:-- 注释,
    # 第四部分:' and password='%s',第四部分会当成注释内容。所以执行该程序会显示登录成功。
    cursor.execute(sql)         #执行sql语句
    result = cursor.fetchone()  #返回第一行内容
    #关闭连接
    cursor.close()
    conn.close()
    
    if result:
        print('登录成功')
    else:
        print('登录失败')
    
    import pymysql
    user = input("username:")
    pwd = input("password:")
    
    conn = pymysql.connect(host="localhost",user='root',password='',database="db3")
    cursor = conn.cursor()
    sql = "select * from userinfo where username=%s and pwd=%s"
    # cursor.execute(sql,(user,pwd))
    cursor.execute(sql,[user,pwd])    #cursor.execute(sql,user,pwd)也可写成cursor.execute(sql,[user,pwd]),效果一样
    # cursor.execute(sql,{'u':user,'p':pwd})    #sql中加入key值,打印结果就会变成字典的格式而不是元组格式
    result = cursor.fetchone()                  #取一行
    cursor.close()
    conn.close()
    if result:
        print('登录成功')
    else:
        print('登录失败')
    
    print(result)
    

      

    import pymysql
    
    # 增加,删,该
    #增
    # conn = pymysql.connect(host="localhost",user='root',password='',database="db3")
    # cursor = conn.cursor()
    # sql = "insert into userinfo(username,pwd) values('root','123123')"
    # 受影响的行数
    # r = cursor.execute(sql)
    # #  ******
    # conn.commit()     #对数据库有改变均要执行conn.commit()命令,提交给数据库。所以增删改均需有这条命令,查不需要。
    # cursor.close()
    # conn.close()
    
    # conn = pymysql.connect(host="localhost",user='root',password='',database="db3")
    # cursor = conn.cursor()
    # # sql = "insert into userinfo(username,pwd) values(%s,%s)"
    # # cursor.execute(sql,(user,pwd,))
    #
    # sql = "insert into userinfo(username,password) values(%s,%s)"
    # # 受影响的行数
    # r = cursor.executemany(sql,[('egon','sb'),('laoyao','BS')])
    # #  ******
    # conn.commit()
    # cursor.close()
    # conn.close()
    
    
    
    
    # 查
    # conn = pymysql.connect(host="localhost",user='root',password='',database="db666")
    # cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    # sql = "select * from userinfo"
    # cursor.execute(sql)
    
    # cursor.scroll(1,mode='relative')  # 相对当前位置移动
    # cursor.scroll(2,mode='absolute') # 相对绝对位置移动
    # result = cursor.fetchone()
    # print(result)
    # result = cursor.fetchone()
    # print(result)
    # result = cursor.fetchone()
    # print(result)
    # result = cursor.fetchall()
    # print(result)
    
    
    # result = cursor.fetchmany(4)
    # print(result)
    # cursor.close()
    # conn.close()
    
    
    
    
    # 新插入数据的自增ID: cursor.lastrowid
    # import pymysql
    #
    # conn = pymysql.connect(host="localhost",user='root',password='',database="db3")
    # cursor = conn.cursor()
    # sql = "insert into userinfo(username,pwd) values('asdfasdf','123123')"
    # cursor.execute(sql)
    # conn.commit()
    # print(cursor.lastrowid)       #lastrowid最后一个自增id
    # cursor.close()
    # conn.close()

      

    6、作业

    作业:
            参考表结构:
                用户类型
    
                用户信息
    
                权限
    
                用户类型&权限
            功能:
    
                # 登陆、注册、找回密码
                # 用户管理
                # 用户类型
                # 权限管理
                # 分配权限
    
            特别的:程序仅一个可执行文件
    create database wuSir default character set utf8 collate utf8_general_ci;
    
    use wuSir;
    
    
    create table auth_info(
        aid int not null auto_increment primary key,
        auth_name varchar(32),
        unique(auth_name)
        )engine=innodb default charset=utf8;
    
    
    create table user_info(
        uid int not null auto_increment primary key,
        name varchar(32),
        passwd varchar(32),
        sex ENUM("","")
        )engine=innodb default charset=utf8;
    
    create table user_auth(
        id int,
        auth_id int,
        constraint auth_info foreign key(auth_id) references auth_info(aid),
        constraint user_info foreign key(id) references user_info(uid)
        )engine=innodb default charset=utf8;
    
    
    
    insert into auth_info(auth_name) values("订单管理"),("用户管理"),("菜单管理"),("权限分配"),("Bug管理");
    
    insert into user_info(name,passwd,sex) values("alex",123,""),("egon",123,"");
    
    insert into user_auth(id,auth_id) values(1,1),(2,1),(2,2),(2,3);
    创建库表 SQL
    import pymysql
    
    
    user = input("please input name: ").strip()
    passwd = input("please input passwd: ").strip()
    
    
    conn = pymysql.connect(host="10.37.129.3",port=3306,user="egon",passwd="123456",db="wuSir",charset="utf8")
    
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    sql = "select * from user_info where name=%s and passwd=%s"
    
    cursor.execute(sql,(user,passwd,))
    result = cursor.fetchone()
    
    if result["name"] == user and result["passwd"] == passwd:
        uid = result["uid"]
        # print(uid)
        sql = "select auth_name from auth_info where aid in (select auth_id from user_auth where id =%s)"
    
        cursor.execute(sql,(uid,))
        result = cursor.fetchall()
        for i in result:
            print(i["auth_name"])
    
    else:
        print("error")
    
    cursor.close()
    conn.close()
    Python 代码

    SQLAchemy

    SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。

    安装:

    pip3 install SQLAlchemy
    

    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
    

    一、内部处理

    使用 Engine/ConnectionPooling/Dialect 进行数据库操作,Engine使用ConnectionPooling连接数据库,然后再通过Dialect执行SQL语句。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from sqlalchemy import create_engine
      
      
    engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)
      
    # 执行SQL
    # cur = engine.execute(
    #     "INSERT INTO hosts (host, color_id) VALUES ('1.1.1.22', 3)"
    # )
      
    # 新插入行自增ID
    # cur.lastrowid
      
    # 执行SQL
    # cur = engine.execute(
    #     "INSERT INTO hosts (host, color_id) VALUES(%s, %s)",[('1.1.1.22', 3),('1.1.1.221', 3),]
    # )
      
      
    # 执行SQL
    # cur = engine.execute(
    #     "INSERT INTO hosts (host, color_id) VALUES (%(host)s, %(color_id)s)",
    #     host='1.1.1.99', color_id=3
    # )
      
    # 执行SQL
    # cur = engine.execute('select * from hosts')
    # 获取第一行数据
    # cur.fetchone()
    # 获取第n行数据
    # cur.fetchmany(3)
    # 获取所有数据
    # cur.fetchall()
    

    二、ORM功能使用

    使用 ORM/Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect 所有组件对数据进行操作。根据类创建对象,对象转换成SQL,执行SQL。

    1、创建表

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
    from sqlalchemy.orm import sessionmaker, relationship
    from sqlalchemy import create_engine
     
    engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)
     
    Base = declarative_base()
     
    # 创建单表
    class Users(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        extra = Column(String(16))
     
        __table_args__ = (
        UniqueConstraint('id', 'name', name='uix_id_name'),
            Index('ix_id_name', 'name', 'extra'),
        )
     
     
    # 一对多
    class Favor(Base):
        __tablename__ = 'favor'
        nid = Column(Integer, primary_key=True)
        caption = Column(String(50), default='red', unique=True)
     
     
    class Person(Base):
        __tablename__ = 'person'
        nid = Column(Integer, primary_key=True)
        name = Column(String(32), index=True, nullable=True)
        favor_id = Column(Integer, ForeignKey("favor.nid"))
     
     
    # 多对多
    class Group(Base):
        __tablename__ = 'group'
        id = Column(Integer, primary_key=True)
        name = Column(String(64), unique=True, nullable=False)
        port = Column(Integer, default=22)
     
     
    class Server(Base):
        __tablename__ = 'server'
     
        id = Column(Integer, primary_key=True, autoincrement=True)
        hostname = Column(String(64), unique=True, nullable=False)
     
     
    class ServerToGroup(Base):
        __tablename__ = 'servertogroup'
        nid = Column(Integer, primary_key=True, autoincrement=True)
        server_id = Column(Integer, ForeignKey('server.id'))
        group_id = Column(Integer, ForeignKey('group.id'))
     
     
    def init_db():
        Base.metadata.create_all(engine)
     
     
    def drop_db():
        Base.metadata.drop_all(engine)
    

    注:设置外检的另一种方式 ForeignKeyConstraint(['other_id'], ['othertable.other_id'])

    2、操作表

    表结构 + 数据库连接

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
    from sqlalchemy.orm import sessionmaker, relationship
    from sqlalchemy import create_engine
    
    engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)
    
    Base = declarative_base()
    
    # 创建单表
    class Users(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        extra = Column(String(16))
    
        __table_args__ = (
        UniqueConstraint('id', 'name', name='uix_id_name'),
            Index('ix_id_name', 'name', 'extra'),
        )
    
        def __repr__(self):
            return "%s-%s" %(self.id, self.name)
    
    # 一对多
    class Favor(Base):
        __tablename__ = 'favor'
        nid = Column(Integer, primary_key=True)
        caption = Column(String(50), default='red', unique=True)
    
        def __repr__(self):
            return "%s-%s" %(self.nid, self.caption)
    
    class Person(Base):
        __tablename__ = 'person'
        nid = Column(Integer, primary_key=True)
        name = Column(String(32), index=True, nullable=True)
        favor_id = Column(Integer, ForeignKey("favor.nid"))
        # 与生成表结构无关,仅用于查询方便
        favor = relationship("Favor", backref='pers')
    
    # 多对多
    class ServerToGroup(Base):
        __tablename__ = 'servertogroup'
        nid = Column(Integer, primary_key=True, autoincrement=True)
        server_id = Column(Integer, ForeignKey('server.id'))
        group_id = Column(Integer, ForeignKey('group.id'))
        group = relationship("Group", backref='s2g')
        server = relationship("Server", backref='s2g')
    
    class Group(Base):
        __tablename__ = 'group'
        id = Column(Integer, primary_key=True)
        name = Column(String(64), unique=True, nullable=False)
        port = Column(Integer, default=22)
        # group = relationship('Group',secondary=ServerToGroup,backref='host_list')
    
    
    class Server(Base):
        __tablename__ = 'server'
    
        id = Column(Integer, primary_key=True, autoincrement=True)
        hostname = Column(String(64), unique=True, nullable=False)
    
    
    
    
    def init_db():
        Base.metadata.create_all(engine)
    
    
    def drop_db():
        Base.metadata.drop_all(engine)
    
    
    Session = sessionmaker(bind=engine)
    session = Session()
    

    增 

    obj = Users(name="alex0", extra='sb')
    session.add(obj)
    session.add_all([
        Users(name="alex1", extra='sb'),
        Users(name="alex2", extra='sb'),
    ])
    session.commit()
    

    session.query(Users).filter(Users.id > 2).delete()
    session.commit()
    

    session.query(Users).filter(Users.id > 2).update({"name" : "099"})
    session.query(Users).filter(Users.id > 2).update({Users.name: Users.name + "099"}, synchronize_session=False)
    session.query(Users).filter(Users.id > 2).update({"num": Users.num + 1}, synchronize_session="evaluate")
    session.commit()
    

    ret = session.query(Users).all()
    ret = session.query(Users.name, Users.extra).all()
    ret = session.query(Users).filter_by(name='alex').all()
    ret = session.query(Users).filter_by(name='alex').first()
    
    ret = session.query(Users).filter(text("id<:value and name=:name")).params(value=224, name='fred').order_by(User.id).all()
    
    ret = session.query(Users).from_statement(text("SELECT * FROM users where name=:name")).params(name='ed').all()
    

    其他

    # 条件
    ret = session.query(Users).filter_by(name='alex').all()
    ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
    ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
    ret = session.query(Users).filter(Users.id.in_([1,3,4])).all()
    ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all()
    ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
    from sqlalchemy import and_, or_
    ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
    ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
    ret = session.query(Users).filter(
        or_(
            Users.id < 2,
            and_(Users.name == 'eric', Users.id > 3),
            Users.extra != ""
        )).all()
    
    
    # 通配符
    ret = session.query(Users).filter(Users.name.like('e%')).all()
    ret = session.query(Users).filter(~Users.name.like('e%')).all()
    
    # 限制
    ret = session.query(Users)[1:2]
    
    # 排序
    ret = session.query(Users).order_by(Users.name.desc()).all()
    ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()
    
    # 分组
    from sqlalchemy.sql import func
    
    ret = session.query(Users).group_by(Users.extra).all()
    ret = session.query(
        func.max(Users.id),
        func.sum(Users.id),
        func.min(Users.id)).group_by(Users.name).all()
    
    ret = session.query(
        func.max(Users.id),
        func.sum(Users.id),
        func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()
    
    # 连表
    
    ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()
    
    ret = session.query(Person).join(Favor).all()
    
    ret = session.query(Person).join(Favor, isouter=True).all()
    
    
    # 组合
    q1 = session.query(Users.name).filter(Users.id > 2)
    q2 = session.query(Favor.caption).filter(Favor.nid < 2)
    ret = q1.union(q2).all()
    
    q1 = session.query(Users.name).filter(Users.id > 2)
    q2 = session.query(Favor.caption).filter(Favor.nid < 2)
    ret = q1.union_all(q2).all()
    

     示例:

    1、查询语法

    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
    from sqlalchemy.orm import sessionmaker, relationship
    from sqlalchemy import create_engine
    
    Base = declarative_base()
    
    
    # 创建单表
    class UserType(Base):
        __tablename__ = 'usertype'
        id = Column(Integer, primary_key=True, autoincrement=True)
        title = Column(String(32), nullable=True, index=True)
    
    class Users(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True, autoincrement=True)  #主键    自增
        name = Column(String(32), nullable=True)                    #不为空
        email = Column(String(16), unique=True)                     #唯一
        user_type_id = Column(Integer,ForeignKey("usertype.id"))    #外键
    
        __table_args__ = (
            UniqueConstraint('name', 'email', name='uix_id_name'),  #联合唯一索引
            Index('ix_n_ex','name', 'email',),
        )
    
    
    engine = create_engine("mysql+pymysql://egon:123456@10.37.129.3:3306/day63?charset=utf8", max_overflow=5)
    
    Session = sessionmaker(bind=engine)
    session = Session()
    
    
    # ret = session.query(Users)
        #SELECT users.id AS users_id, users.name AS users_name, users.email AS users_email, users.user_type_id AS users_user_type_id FROM users
    
    # ret = session.query(Users).all()
        #[<__main__.Users object at 0x1037620f0>, <__main__.Users object at 0x103762160>, <__main__.Users object at 0x1037621d0>]
    
    # ret = session.query(Users.name, Users.email).all()
    #     [('alex', '163'), ('egon', '173'), ('wuSir', '183')]
    
    # ret = session.query(Users).filter_by(name='alex').all()
    #     [<__main__.Users object at 0x103759198>]
    
    # ret = session.query(Users).filter_by(name='alex').first()
    #     <__main__.Users object at 0x103758240>
    
    #user_list = session.query(UserType.id,UserType.title).filter(UserType.id>=1).all()
    #   [(1, '普通用户'), (2, '黄金用户')]    
    
    session.commit()
    session.close()
    

    2、插入语法

    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
    from sqlalchemy.orm import sessionmaker, relationship
    from sqlalchemy import create_engine
    
    Base = declarative_base()
    
    
    # 创建单表
    class UserType(Base):
        __tablename__ = 'usertype'
        id = Column(Integer, primary_key=True, autoincrement=True)
        title = Column(String(32), nullable=True, index=True)
    
    class Users(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True, autoincrement=True)  #主键    自增
        name = Column(String(32), nullable=True)                    #不为空
        email = Column(String(16), unique=True)                     #唯一
        user_type_id = Column(Integer,ForeignKey("usertype.id"))    #外键
    
        __table_args__ = (
            UniqueConstraint('name', 'email', name='uix_id_name'),  #联合唯一索引
            Index('ix_n_ex','name', 'email',),
        )
    
    
    engine = create_engine("mysql+pymysql://egon:123456@10.37.129.3:3306/day63?charset=utf8", max_overflow=5)
    
    
    Session = sessionmaker(bind=engine)
    session = Session()
    
    
    #方式一:
    # obj = UserType(title="普通用户")
    # obj1 = UserType(title="黄金用户")
    # session.add(obj)
    # session.add(obj1)
    
    
    #方式二:
    
    objs= [
      Users(name="alex",email="163",user_type_id=1),
      Users(name="egon",email="173",user_type_id=1),
      Users(name="tom",email="183",user_type_id=2)
    ]
    
    session.add_all(objs)
    
    
    session.commit()
    session.close()
    

    3、删除 修改 语法

    #删除
    # session.query(Users).filter(Users.id>1).delete()
    
    
    #修改
    
    #session.query(Users).filter(Users.id > 2).update({"name" : "099"})
    #session.query(Users).filter(Users.id > 2).update({Users.name: Users.name + "099"}, synchronize_session=False)
    #session.query(Users).filter(Users.id > 2).update({"num": Users.num + 1}, synchronize_session="evaluate")
    
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index,CHAR,VARCHAR
    from sqlalchemy.orm import sessionmaker, relationship
    from sqlalchemy import create_engine
    
    # 创建对象的基类:
    Base = declarative_base()
    
    
    # 创建单表
    """
    1   白金
    2   黑金
    obj.xx ==> [obj,obj...]
    """
    # 创建表单usertype
    class UserType(Base):
        # 表的名字:
        __tablename__ = 'usertype'
        # 表的结构:
        id = Column(Integer, primary_key=True, autoincrement=True)
        title = Column(VARCHAR(32), nullable=True, index=True)
    
    
    """
    1   方少伟   1
    2   成套     1
    3   小白     2
    # 正向
    ut = relationship(backref='xx')
    obj.ut ==> 1   白金
    """
    
    class Users(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True, autoincrement=True)
        name = Column(VARCHAR(32), nullable=True, index=True)
        email = Column(VARCHAR(16), unique=True)
        user_type_id = Column(Integer,ForeignKey("usertype.id"))
    
        user_type = relationship("UserType",backref='xxoo')     # 一对多:
        # __table_args__ = (
        #     UniqueConstraint('id', 'name', name='uix_id_name'),
        #     Index('ix_n_ex','name', 'email',),
        # )
    
    
    def create_db():
        engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/s4day62db?charset=utf8", max_overflow=5)
        # 新增表
        Base.metadata.create_all(engine)
    
    def drop_db():
        engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/s4day62db?charset=utf8", max_overflow=5)
        # 删除表
        Base.metadata.drop_all(engine)
    
    # 初始化数据库连接:(create_engine()用来初始化数据库连接)
    engine = create_engine("mysql+pymysql://root:@127.0.0.1:3306/db5?charset=utf8", max_overflow=5)
    #'数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'
    # mysql使用的数据库,pymysql模板,root账户,root : 后加密码,mysql客户端未设置密码。db5为数据库,max_overflow代表最大连接数量
    
    
    # 新增表
    Base.metadata.create_all(engine)
    # 创建Session类型:
    Session = sessionmaker(bind=engine)
    # 创建session对象:
    session = Session()
    
    # 类 -> 表
    # 对象 -> 行
    # ###### 增加 ######
    ## 创建新obj1对象
    # obj1 = UserType(title='普通用户')
    # # 添加到session:
    # session.add(obj1)
    
    # objs =[
    #   UserType(title='超级用户'),
    #   UserType(title='白金用户'),
    #   UserType(title='黑金用户'),
    # ]
    # session.add_all(objs)
    
    # ###### 查 ######
    # print(session.query(UserType))
    ## 创建Query查询,调用one()返回一行,如果调用all()则返回所有行:
    # user_type_list = session.query(UserType).all()  #session.query(UserType)相当于迭代器,不加 .all()的话,for循环结果也是一样的
    # for row in user_type_list:
    #     print(row.id,row.title)
    
    
    
    # #select UserType.id,UserType.title  UserType where UserType.id > 2                #sql语句
    # user_type_list = session.query(UserType.id,UserType.title).filter(UserType.id > 2)  #使用框架sqlalchemy来实现,filter过滤
    # for row in user_type_list:
    #     print(row.id,row.title)
    
    # print(user_type_list) #打印结果:SELECT usertype.id AS usertype_id, usertype.title AS usertype_title FROM usertype WHERE usertype.id > %(id_1)s
    
    
    
    
    # 分组,排序,连表,通配符,子查询,limit,union,where,原生SQL
    # ret = session.query(Users, UserType)
    # select * from user,usertype;
    #
    # ret = session.query(Users, UserType).filter(Users.usertype_id==UserType.id)
    # select * from user,usertype whre user.usertype_id = usertype.id
    
    # result = session.query(Users).join(UserType)
    # print(result)
    
    # result = session.query(Users).join(UserType,isouter=True)
    # print(result)
    
    
    
    # sql语句用sqlalchemy框架实现:
    # 1.
    # select * from b where id in (select id from tb2)      #sql语句
    #sqlalchemy框架实现: ...
    
    # 2
    # select * from (select * from UserType where UserType.id > 0) as B     #sql语句
    #sqlalchemy框架实现:
    # q1 = session.query(UserType).filter(UserType.id > 0).subquery()   #subquery()子查询
    # print(q1)
    # result = session.query(q1).all()
    # print(result)
    
    
    # 3
    # select id ,(select * from users where users.user_type_id=usertype.id) from usertype;  #sql语句,嵌套sql语句select * from users where users.user_type_id=usertype.id
    #sqlalchemy框架实现:
    # session.query(UserType,session.query(Users).filter(Users.id == 1).subquery())  #subquery()子查询的固定用法,有嵌套sql语句为子查询,需使用subquery()
    # session.query(UserType,Users)
    # result = session.query(UserType.id,session.query(Users).as_scalar())  #as_scalar() 相当于临时表的固定用法
    # print(result)
    # result = session.query(UserType.id,session.query(Users).filter(Users.user_type_id==UserType.id).as_scalar())
    # print(result)
    
    
    
    
    
    
    # 问题1. 获取用户信息以及与其关联的用户类型名称(FK,Relationship=>正向操作)
    # user_list = session.query(Users,UserType).join(UserType,isouter=True)   #联表left ... join ...on...
    # # print(user_list)
    # for row in user_list:
    #     print(row[0].id,row[0].name,row[0].email,row[0].user_type_id,row[1].title)      # row[0] 为表Users,row[1]为表UserType
    
    # user_list= session.query(Users.name,UserType.title)     #不同表不可以直接获取,需要联表获取
    # print("user_list:",user_list) #SELECT users.name AS users_name, usertype.title AS usertype_title FROM users, usertype
    
    # user_list = session.query(Users.name,UserType.title).join(UserType,isouter=True).all()    #左联表
    # user_list = session.query(UserType.title,Users.name).join(Users,isouter=True).all()        #换个位置后,就变成右联表
    #isouter=True代表左联表left ... join ...on...,不加isouter=True代表inner ... join ... on ...
    # print("user_list:",user_list)
    # for row in user_list:
    #     print("row:",row)           #打印结果是元组形式,所以row[0]与row.name,row[1]和row.title打印结果是一样的
    #     print(row[0],row[1],row.name,row.title)
    
    
    # user_list = session.query(Users)
    # for row in user_list:
    #     print(row.name,row.id,row.user_type.title)  #row.user_type.title,建表users时使用了user_type = relationship("UserType",backref='xxoo')
    # #--->xyp 1 超级用户     #row.user_type.title,表user和usertype建立了连接,user的行可以直接调用usertype的内容
    # #    xyp2 2 白金用户
    
    
    
    # 问题2. 获取用户类型
    type_list = session.query(UserType)
    for row in type_list:
        print(row.id,row.title,session.query(Users).filter(Users.user_type_id == row.id).all())
        # --->2 白金用户 [<__main__.Users object at 0x00000000039639E8>]
        #     1 超级用户 [<__main__.Users object at 0x0000000003963B00>]
        #     3 黑金用户[]          #因为user表仅二行,所以usertype表的id就无法与Users第三行的user_type_id 匹配
    
    
    # type_list = session.query(UserType)
    # for row in type_list:
    #     print(row.id,row.title,row.xxoo)        #建表users时使用了user_type = relationship("UserType",backref='xxoo')
        # --->2 白金用户 [<__main__.Users object at 0x0000000003963DA0>]
        #     1 超级用户 [<__main__.Users object at 0x0000000003963F98>]
        #     3 黑金用户 []
    
    
    
    
    
    # ###### 删除 ######
    # session.query(UserType.id,UserType.title).filter(UserType.id > 2).delete()    # 删除前需先查
    
    # ###### 修改 ######
    #  修改前需先查
    #改变全部title列为"黑金":
    # session.query(UserType.id,UserType.title).filter(UserType.id > 0).update({"title" : "黑金"})
    #改变UserType.id > 0的title列加字符串"x",synchronize_session=False用在修改字符串固定用法
    # session.query(UserType.id,UserType.title).filter(UserType.id > 0).update({UserType.title: UserType.title + "x"}, synchronize_session=False)
    #改变UserType.id > 0的title列,num列建表时未建,Users.num + 1,整型的计算。synchronize_session="evaluate" 用在修改整型固定用法
    # session.query(UserType.id,UserType.title).filter(UserType.id > 0).update({"num": Users.num + 1}, synchronize_session="evaluate")
    
    
    # 提交即保存到数据库:
    session.commit()
    # 关闭session:
    session.close()
    补充

    更多功能参见文档,猛击这里下载PDF

  • 相关阅读:
    线段树专辑—— pku 1436 Horizontally Visible Segments
    线段树专辑——pku 3667 Hotel
    线段树专辑——hdu 1540 Tunnel Warfare
    线段树专辑—— hdu 1828 Picture
    线段树专辑—— hdu 1542 Atlantis
    线段树专辑 —— pku 2482 Stars in Your Window
    线段树专辑 —— pku 3225 Help with Intervals
    线段树专辑—— hdu 1255 覆盖的面积
    线段树专辑—— hdu 3016 Man Down
    Ajax跨域访问
  • 原文地址:https://www.cnblogs.com/xuyaping/p/7106443.html
Copyright © 2020-2023  润新知