zoukankan      html  css  js  c++  java
  • python学习之路-13

    SQLAlchemy ORM框架

    连表操作

    • 一对多

      • 创建表 指定约束 ForeignKey
      
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      # 一对多
      class Group(Base):
          __tablename__ = "group"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          caption = Column          # 组名
      
      
      class User(Base):
          __tablename__ = "user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
          group_id = Column(Integer, ForeignKey("group.nid"))  # 外键
      
      
      Base.metadata.create_all(engine)
      
      • 插入数据
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      
      # 单表
      class Test(Base):
          __tablename__ = "test"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          name = Column(String(32))
      
      
      # 一对多
      class Group(Base):
          __tablename__ = "group"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          caption = Column(String(32))          # 组名
      
      
      class User(Base):
          __tablename__ = "user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
          group_id = Column(Integer, ForeignKey("group.nid"))  # 外键
      
      
      # Base.metadata.create_all(engine)    # 创建表
      # Base.metadata.drop_all(engine)    # 删除表
      
      Session = sessionmaker(bind=engine)
      session = Session()
      
      ### 添加数据
      # 向表中添加单条数据
      session.add(Group("dba"))
      session.add(Group("ddd"))
      
      # 向表中添加多条数据
      session.add_all(
          [
              User(username="a", group_id=1),
              User(username="b", group_id=2),
              User(username="c", group_id=1)
          ]
      )
      
      session.commit()
      
      • 查询数据
      
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      
      ### 创建表结构
      # 单表
      class Test(Base):
          __tablename__ = "test"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          name = Column(String(32))
      
      
      # 一对多
      class Group(Base):
          __tablename__ = "group"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          caption = Column(String(32))          # 组名
      
      
      class User(Base):
          __tablename__ = "user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
          group_id = Column(Integer, ForeignKey("group.nid"))  # 外键
      
          # 与生成表结构无关,仅用于更方便的进行连表查询
          group = relationship("Group", backref="user")
      
          def __repr__(self):
              temp = "%s - %s - %s" % (self.nid, self.username, self.group_id)
              return temp
      
      
      # Base.metadata.create_all(engine)    # 创建表
      # Base.metadata.drop_all(engine)    # 删除表
      
      
      Session = sessionmaker(bind=engine)
      session = Session()
      
      """
      ### 添加数据
      # 向表中添加单条数据
      session.add(Group("dba"))
      session.add(Group("ddd"))
      
      # 向表中添加多条数据
      session.add_all(
          [
              User(username="a", group_id=1),
              User(username="b", group_id=2),
              User(username="c", group_id=1)
          ]
      )
      
      session.commit()
      """
      
      
      # # 查询单表中所有数据
      # ret = session.query(User).all()
      # print(ret)  # 输出User类中__repr__方法中返回的字符串
      # for obj in ret:
      #     print(obj.nid, obj.username, obj.group_id)
      #
      # # 通过指定列查询
      # ret = session.query(User.nid, User.username).all()
      # print(ret)  # 返回一个列表,列表中包含每一行的数据  [(2, 'a'), (3, 'b'), (4, 'c')]
      
      # # 根据指定条件查询
      # ret = session.query(User).filter(User.username == "a").all()
      # obj = ret[0]
      # print(obj.nid, obj.username, obj.group_id)
      
      # 连表查询
      
      # 通过join进行连表查询
      # ret = session.query(User).join(Group)   # 返回执行的sql语句
      # print(ret)
      # print("------")
      # ret = session.query(User).join(Group).all()
      # for obj in ret:
      #     print(obj.nid, obj.username, obj.group_id)
      #
      # ret = session.query(User, Group).join(Group).all()
      # print(ret)
      #
      #
      # ret = session.query(User.username, Group.caption).join(Group).all()
      # print(ret)
      
      # 通过relationship在创建表的类中指定连表的对应关系,然后进行连表查询
      # 正向查询  (正向查找不能够过滤组的字段)
      ret = session.query(User).all()
      for obj in ret:
          # obj代指user表中的每一行数据
          # obj.group代指obj当前对应的group表中数据的对象
          print(obj.nid, obj.username, obj.group_id, obj.group, obj.group.nid, obj.group.caption)
      
      
      # 反向查询
      # 查找所有组名为dba的用户信息
      obj = session.query(Group).filter(Group.caption=="dba").first()
      print(obj.nid, obj.caption, obj.user)    # obj.user 这个地方的user是在User类中使用relationship创建对应关系中 backref对应的值
      
    • 多对多

      • 原始方法和新式方法1
      ### 关系在第三张表中
      
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      
      class Host(Base):
          """
          主机表
          """
          __tablename__ = "host"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          hostname = Column(String(32))
          port = Column(String(32))
          ip = Column(String(32))
      
      
      class HostUser(Base):
          """
          登录主机的用户表
          """
          __tablename__ = "host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
      
      
      class Host_HostUser(Base):
          """
          关系表
          """
          __tablename__ = "host_to_host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          host_id = Column(Integer, ForeignKey("host.nid"))
          host_user_id = Column(Integer, ForeignKey("host_user.nid"))
      
          host = relationship("Host", backref="h")
          host_user = relationship("HostUser", backref="u")
      
      # Base.metadata.create_all(engine)    # 创建表
      
      Session = sessionmaker(bind=engine)
      session = Session()
      
      # # 向host主机表中添加多条数据
      # session.add_all(
      #     [
      #         Host(hostname="c1", port="22", ip="1.1.1.1"),
      #         Host(hostname="c2", port="22", ip="1.1.1.2"),
      #         Host(hostname="c3", port="22", ip="1.1.1.3"),
      #     ]
      # )
      
      # # 向host_user登录主机用户表中添加多条数据
      # session.add_all(
      #     [
      #         HostUser(username="root"),
      #         HostUser(username="aa"),
      #         HostUser(username="bb"),
      #         HostUser(username="cc"),
      #     ]
      # )
      
      
      # # 向host_to_host_user关系表中添加多条数据
      # session.add_all(
      #     [
      #         Host_HostUser(host_id=1, host_user_id=1),
      #         Host_HostUser(host_id=1, host_user_id=2),
      #         Host_HostUser(host_id=1, host_user_id=3),
      #         Host_HostUser(host_id=1, host_user_id=4),
      #         Host_HostUser(host_id=2, host_user_id=2),
      #         Host_HostUser(host_id=2, host_user_id=4),
      #         Host_HostUser(host_id=3, host_user_id=1),
      #         Host_HostUser(host_id=3, host_user_id=3),
      #     ]
      # )
      
      
      # session.commit()
      
      
      # 需求:找出能够登录主机名为c1的所有用户
      # ### 原始方式
      # # 从host表中将找到主机名为c1的nid
      # host_obj = session.query(Host).filter(Host.hostname == "c1").first()
      #
      # # 通过主机名为c1的nid在关系表中找到用户的id
      # host_2_host_user = session.query(Host_HostUser.host_user_id).filter(Host_HostUser.host_id==host_obj.nid).all()
      #
      # r = zip(*host_2_host_user)
      # users = session.query(HostUser.username).filter(HostUser.nid.in_(list(r)[0])).all()
      # print(users)
      
      ### 原始方式结合
      ret = session.query(HostUser.username).filter(HostUser.nid.in_(session.query(Host_HostUser.host_user_id).filter(Host_HostUser.host_id == session.query(Host.nid).filter(Host.hostname == 'c1')))).all()
      print(ret)
      
      ### 新式方法
      # 通过在Host_HostUser类中使用relationship建立与Host类和HostUser类建立关系,然后使用反向查询和正向询进行查找
      host_obj = session.query(Host).filter(Host.hostname=="c1").first()
      for item in host_obj.h:   # host_obj.h 反向查询
          print(item.host_user.username)  # item.host_user.username  正向查询
      
      • 新式方法2
      ### 关系在第1张表中 secondary=Host_HostUser.__table__ 要将关系表放在最上面 如果不使用lambda则应该将关系表放在最上面
      
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      
      class Host_HostUser(Base):
          """
          关系表
          """
          __tablename__ = "host_to_host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          host_id = Column(Integer, ForeignKey("host.nid"))
          host_user_id = Column(Integer, ForeignKey("host_user.nid"))
      
      
      class Host(Base):
          """
          主机表
          """
          __tablename__ = "host"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          hostname = Column(String(32))
          port = Column(String(32))
          ip = Column(String(32))
      
          host_user = relationship("HostUser",
                                   secondary=Host_HostUser.__table__,
                                   backref="h")
      
      
      class HostUser(Base):
          """
          登录主机的用户表
          """
          __tablename__ = "host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
      
      
      # Base.metadata.create_all(engine)    # 创建表
      
      Session = sessionmaker(bind=engine)
      session = Session()
      
      # # 向host主机表中添加多条数据
      # session.add_all(
      #     [
      #         Host(hostname="c1", port="22", ip="1.1.1.1"),
      #         Host(hostname="c2", port="22", ip="1.1.1.2"),
      #         Host(hostname="c3", port="22", ip="1.1.1.3"),
      #     ]
      # )
      
      # # 向host_user登录主机用户表中添加多条数据
      # session.add_all(
      #     [
      #         HostUser(username="root"),
      #         HostUser(username="aa"),
      #         HostUser(username="bb"),
      #         HostUser(username="cc"),
      #     ]
      # )
      
      
      # # 向host_to_host_user关系表中添加多条数据
      # session.add_all(
      #     [
      #         Host_HostUser(host_id=1, host_user_id=1),
      #         Host_HostUser(host_id=1, host_user_id=2),
      #         Host_HostUser(host_id=1, host_user_id=3),
      #         Host_HostUser(host_id=1, host_user_id=4),
      #         Host_HostUser(host_id=2, host_user_id=2),
      #         Host_HostUser(host_id=2, host_user_id=4),
      #         Host_HostUser(host_id=3, host_user_id=1),
      #         Host_HostUser(host_id=3, host_user_id=3),
      #     ]
      # )
      
      # session.commit()
      
      # 需求:找出能够登录主机名为c1的所有用户
      ### 新式方法二
      
      host_obj = session.query(Host).filter(Host.hostname=="c1").first()
      print(host_obj.host_user)
      
      • 新式方法三
      ### secondary="host_to_host_user" 关系表无顺序要求 如果不使用lambda则应该将关系表放在最上面
      
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      
      class Host(Base):
          """
          主机表
          """
          __tablename__ = "host"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          hostname = Column(String(32))
          port = Column(String(32))
          ip = Column(String(32))
      
          host_user = relationship("HostUser",
                                   secondary="host_to_host_user",
                                   backref="h")
      
      
      class HostUser(Base):
          """
          登录主机的用户表
          """
          __tablename__ = "host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
      
      
      class Host_HostUser(Base):
          """
          关系表
          """
          __tablename__ = "host_to_host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          host_id = Column(Integer, ForeignKey("host.nid"))
          host_user_id = Column(Integer, ForeignKey("host_user.nid"))
      
      
      # Base.metadata.create_all(engine)    # 创建表
      
      Session = sessionmaker(bind=engine)
      session = Session()
      
      ### 新式方法三
      
      host_obj = session.query(Host).filter(Host.hostname=="c1").first()
      print(host_obj.host_user)
      
      • 新式方法四
      ### secondary=lambda : Host_HostUser.__table__  如果不使用lambda则应该将关系表放在最上面
      	
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      
      class Host(Base):
          """
          主机表
          """
          __tablename__ = "host"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          hostname = Column(String(32))
          port = Column(String(32))
          ip = Column(String(32))
      
          host_user = relationship("HostUser",
                                   secondary=lambda : Host_HostUser.__table__,
                                   backref="h")
      
      
      class HostUser(Base):
          """
          登录主机的用户表
          """
          __tablename__ = "host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
      
      
      class Host_HostUser(Base):
          """
          关系表
          """
          __tablename__ = "host_to_host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          host_id = Column(Integer, ForeignKey("host.nid"))
          host_user_id = Column(Integer, ForeignKey("host_user.nid"))
      
      
      # Base.metadata.create_all(engine)    # 创建表
      
      Session = sessionmaker(bind=engine)
      session = Session()
      
      ### 新式方法四
      
      host_obj = session.query(Host).filter(Host.hostname=="c1").first()
      print(host_obj.host_user)
      
      • 新式方法五
      ### 关系表需要使用Table()进行创建
      ### relationship 中secondary=Host_HostUser, 如果不使用lambda则应该将关系表放在最上面
      
      from sqlalchemy import create_engine
      from sqlalchemy.ext.declarative import declarative_base
      from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index, Table
      from sqlalchemy.orm import sessionmaker, relationship
      
      engine = create_engine("mysql+pymysql://tuocigaoshou:Eb^BEF38E9FBC36CA775@111.204.117.99:3306/test", max_overflow=5)
      
      Base = declarative_base()
      
      
      Host_HostUser = Table('host_to_host_user', Base.metadata,
                    Column('nid', Integer, primary_key=True, autoincrement=True),
                    Column('host_id', Integer, ForeignKey("host.nid")),
                    Column('host_user_id', Integer, ForeignKey("host_user.nid")),
      )
      
      
      
      class Host(Base):
          """
          主机表
          """
          __tablename__ = "host"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          hostname = Column(String(32))
          port = Column(String(32))
          ip = Column(String(32))
      
          host_user = relationship("HostUser",
                                   secondary=Host_HostUser,
                                   backref="h")
      
      
      class HostUser(Base):
          """
          登录主机的用户表
          """
          __tablename__ = "host_user"
          nid = Column(Integer, primary_key=True, autoincrement=True)
          username = Column(String(32))
      
      
      # Base.metadata.create_all(engine)    # 创建表
      
      Session = sessionmaker(bind=engine)
      session = Session()
      
      ### 新式方法五
      
      host_obj = session.query(Host).filter(Host.hostname=="c1").first()
      print(host_obj.host_user)
      

    paramiko模块

  • 相关阅读:
    window.location.href的使用方法
    hdu 2850 Load Balancing (优先队列 + 贪心)
    几种常见模式识别算法整理和总结
    【DateStructure】 Charnming usages of Map collection in Java
    编写你自己的单点登录(SSO)服务
    微软历史最高市值是多少?
    Tomcat配置一个ip绑定多个域名
    递归算法:求序列的全排列
    SMTP协议分析
    platform_device与platform_driver
  • 原文地址:https://www.cnblogs.com/CongZhang/p/5743587.html
Copyright © 2011-2022 走看看