多对多


  • 游戏和主机关系:
    • 一台server可以属于多个业务线;一个业务线也可以有多台主机(多对多)
    • 此时,需要第三张表,来单独存放关系,
    • 注意:关系表不用手动去管理,自动会变化(下面例子中,从头到尾都没有操控过关系表)
  • 案例:
#!/usr/bin/env python
# -*- encoding:utf-8 -*-


import sqlalchemy
from sqlalchemy import DATE
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

engine = create_engine("mysql+pymysql://root:@127.0.0.1/db01?charset=utf8")
Base = declarative_base()


class Server_Business(Base):
    __tablename__ = 'server_business'
    id = Column(Integer, primary_key=True)
    Server_id = Column(Integer, ForeignKey('server.id'))
    Business_id = Column(Integer, ForeignKey('business.id'))

class Server(Base):
    __tablename__ = 'server'
    id = Column(Integer, primary_key=True)
    name = Column(String(32), nullable=False)
    address = Column(String(32), nullable=False)
    port = Column(Integer, default=22, nullable=False)

    # 'Business' 为类名称,'server_business' 为表名称
    business = relationship('Business', secondary='server_business', backref='server')

class Business(Base):
    __tablename__ = 'business'
    id = Column(Integer, primary_key=True)
    type = Column(String(32), nullable=False)



# Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)


# 插入数据,随便先插入哪个表都行,因为这2张表没有直接的关联关系
Session_cls = sessionmaker(bind=engine)
session = Session_cls()
session.add_all([
    Server(name='node1', address='192.168.1.1', port=22),
    Server(name='node2', address='192.168.1.2', port=22),
    Server(name='node3', address='192.168.1.3', port=22),
    Server(name='node4', address='192.168.1.4', port=22),
    Server(name='node5', address='192.168.1.5', port=22),
    Server(name='node6', address='192.168.1.6', port=22),
])
session.add_all([
    Business(type='youxi'),
    Business(type='yunwei'),
    Business(type='shipin'),
    Business(type='jisuan'),
    Business(type='baobiao'),
])
session.commit()

# 讲 node1 划分给 id 大于 2 的业务线使用 (一台机器属于多个业务线)
server_obj = session.query(Server).filter(Server.name == 'node1').first()
print(server_obj.name, server_obj.port, server_obj.address)
business_obj_lst = session.query(Business).filter(Business.id > 2).all()
server_obj.business = business_obj_lst
session.commit()

# 将 youxi 业务线中,增加 id 大于3 的机器 (一个业务线有多个机器)
business_obj = session.query(Business).filter(Business.type == 'youxi').first()
server_obj_lst = session.query(Server).filter(Server.id > 3).all()
business_obj.server = server_obj_lst
session.commit()


# 查询游戏业务线有哪些主机,这些主机的名称和地址分别为什么
obj_lst = session.query(Business).filter(Business.type == 'youxi').first().server
for obj in obj_lst:
    print(obj.name, obj.address)

# 从游戏业务线中,删除名称为 node4 的主机
business_obj = session.query(Business).filter(Business.type == 'youxi').first()
server_obj = session.query(Server).filter(Server.name == 'node4').first()
business_obj.server.remove(server_obj)

obj_lst2 = session.query(Business).filter(Business.type == 'youxi').first().server
for obj in obj_lst2:
    print(obj.name)  # 此时看到已经没有node4










 

posted on 2017-01-18 10:05  台灯不太亮  阅读(231)  评论(0编辑  收藏  举报

导航