• Python SQLAlchemy之多对多


    1.新建三张表host,host_user,host_to_host_user

    host:

    nid

    hostname
    1 c1
    2 c2
    3 c3
    4 c4
    5 c5

    host_user:

    nid username
    1 root
    2 db
    3 nb
    4 sb

    host_to_host_user:

    nid host_id host_user_id
    1 1 1
    2 1 2
    3 1 3
    4 2 2
    5 2 4
    6 2 3

    第一个问题:我们需要查询c1服务器里面的用户都有哪些?

    如果使用传统的方法,我们使用下面的语句来实现功能:

    #取主机名为c1的服务器ID号
    host_obj = session.query(Host).filter(Host.hostname == 'c1').first()
    #通过获取到的服务器ID号去对应的关系表中找到用户ID,得到一个列表,里面是元祖
    host_2_host_user = session.query(HostToHostUser.host_user_id).filter(HostToHostUser.host_id == host_obj.nid).all()
    # print (host_2_host_user)   #[(1,), (2,), (3,)]
    #处理元祖
    ret = zip(*host_2_host_user)
    # print (list(ret)[0])
    users = session.query(HostUser.username).filter(HostUser.nid.in_(list(ret)[0])).all()
    print (users)
    执行结果:
    [('root',), ('db',), ('nb',)]

    使用新方式来实现,在建表的步骤里面我们加入了新的relationship:

    #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:Passw0rd!@192.168.2.101/beadata", max_overflow=5)
    
    Base = declarative_base()
    
    class Host(Base):
        __tablename__ = 'host'
        nid = Column(Integer,primary_key=True,autoincrement=True)
        hostname = Column(String(32))
    
    class HostUser(Base):
        __tablename__ = 'host_user'
        nid = Column(Integer,primary_key=True,autoincrement=True)
        username = Column(String(32))
    
    class HostToHostUser(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')
    
    Session = sessionmaker(bind=engine)
    session = Session()
    
    # session.add_all([
    #     Host(hostname='c1'),
    #     Host(hostname='c2'),
    #     Host(hostname='c3'),
    #     Host(hostname='c4'),
    #     Host(hostname='c5'),
    # ])
    #
    # session.add_all([
    #     HostUser(username='root'),
    #     HostUser(username='db'),
    #     HostUser(username='nb'),
    #     HostUser(username='sb'),
    # ])
    #
    # session.add_all([
    #     HostToHostUser(host_id='1',host_user_id='1'),
    #     HostToHostUser(host_id='1',host_user_id='2'),
    #     HostToHostUser(host_id='1',host_user_id='3'),
    #     HostToHostUser(host_id='2',host_user_id='2'),
    #     HostToHostUser(host_id='2',host_user_id='4'),
    #     HostToHostUser(host_id='2',host_user_id='3'),
    # ])
    
    host_obj = session.query(Host).filter(Host.hostname == 'c1').first()
    print (host_obj.nid)
    print (host_obj.hostname)
    print (host_obj.h)
    执行结果:
    1
    c1
    [<__main__.HostToHostUser object at 0x0000000003FA3208>, <__main__.HostToHostUser object at 0x0000000003FA3278>, <__main__.HostToHostUser object at 0x0000000003FA32E8>]

    host_obj.h获取到三个对象,然后循环这三个对象,可以得到这三个对象中的host_to_host_user表中的host_user.nid,host_user.host_id,host_user.host_user_id:

    for item in host_obj.h:
        print (item.host_user,item.host_user.username)

    执行结果:
    1
    c1
    [<__main__.HostToHostUser object at 0x0000000003FA2208>, <__main__.HostToHostUser object at 0x0000000003FA2278>, <__main__.HostToHostUser object at 0x0000000003FA22E8>]
    <__main__.HostUser object at 0x0000000003FA28D0> root
    <__main__.HostUser object at 0x0000000003FA2A90> db
    <__main__.HostUser object at 0x0000000003FA2C50> nb
  • 相关阅读:
    mysql中的内连接and 多表查询
    webdriver中的三大等待及窗口的切换
    postman断言
    postman数据驱动ddt
    postman环境变量和全局变量的使用
    postman 接口请求过程
    垃圾脑瘫的坑
    待填的坑
    CF185D
    CF235E 题解(转)
  • 原文地址:https://www.cnblogs.com/python-study/p/5894591.html
Copyright © 2020-2023  润新知