ORM层面外键和多对多关系
- 多对多的关系需要通过一张
中间表
来绑定他们之间的关系。
- 先把两个需要做多对多的模型
定义
出来
- 使用
Table
定义一个中间表,中间表一般就是包含两个模型的外键字段
就可以了,并且让它们两个来作为一复合主键
。
- 在两个需要做多对多的模型中随便选择一个模型,定义一个
relationship
属性,来绑定三者之间的关系,在使用relationship
的时候,需要传入一个secondary=中间表对象名
。
from sqlalchemy import create_engine,Column,Integer,Float,Boolean,DECIMAL,Enum,\
Date,DateTime,Time,String,Text,func,or_,and_,ForeignKey,Table
from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker,relationship,backref
import random
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'first_sqlalchemy'
USERNAME = 'root'
PASSWORD = 'root'
DB_URI ="mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8"\
.format(username=USERNAME,password=PASSWORD,host=HOSTNAME,port=PORT,db=DATABASE)
engine = create_engine(DB_URI)
Base = declarative_base(engine)
session = sessionmaker(engine)()
news_tag = Table( "news_tag", Base.metadata,
Column("news_id",Integer,ForeignKey("news.id"),primary_key=True),
Column("tag_id",Integer,ForeignKey("tag.id"),primary_key=True) )
class News(Base):
__tablename__ = 'news'
id = Column(Integer,primary_key=True,autoincrement=True)
title = Column(String(50),nullable=False)
def __repr__(self):
return "<News(title:%s)>" % self.title
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False)
newss = relationship("News",backref="tags",secondary=news_tag)
def __repr__(self):
return "<Tag(name:%s)>" % self.name
Base.metadata.drop_all()
Base.metadata.create_all()