Python SQLAlchemy之多对多

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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:[email protected]/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

 

以上是关于Python SQLAlchemy之多对多的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在 SQLAlchemy - python 的多对多关系表中添加重复项?

python中flask和sqlalchemy的多对多

059:表关系之多对多

python SQLAlchemy多对多唯一约束仅以一种方式工作

SQLAlchemy 增删改查 一对多 多对多

SQLAlchemy 增删改查 一对多 多对多