【SQLAlchemy】第5节:模型类多对多

【SQLAlchemy】第5节:模型类多对多

1 思路与实现

  • 用户user和帖子forum,存在收藏关系,一个用户可以收藏多个帖子,一个帖子也可以被多个用户收藏,这是一个简单的多对多问题
  • 需要3张表,用户表、帖子表和中间表
  • 如果中间表仅仅保存了用户的id和帖子的id,就太简单了,现在产品经理有这样的需求,需要记录用户的哪个时间收藏了哪个帖子,所以中间表需要多一个字段,DateTime

(多对多关系是MySQL的基础,我假设大家已经具备了这个知识,如果表与表间的定义关系不清楚,可以看下我博客里面关于MySQL的部分)

代码实现:

from sqlalchemy import create_engine
from sqlalchemy import Column, String, Integer, ForeignKey, Table,DateTime
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base


engine = create_engine(
    'mysql+pymysql://root:12345@localhost:3306/db_sqlalchemy_notebook',
    echo=False
)

Base = declarative_base()

import datetime

# 中间表,需要写在最前面
user_forum_collection = Table(
    'user_forum_collection', # 中间表的名字
    Base.metadata, # 传递metadata,记住这个写法就好
    Column('id', Integer, primary_key=True, autoincrement=True), # 如果再中间表中定义主键,除了primary_key=True以外,必须加上autoincrement=True,否则报错
    Column('user_id', Integer, ForeignKey('user.id')), # 引用user.id
    Column('forum_id', Integer, ForeignKey('forum.id')), # 引用forum.id
    Column('createDatetime',DateTime,default=datetime.datetime.now(),nullable=False) # 用户收藏帖子的时间
)


class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    name = Column(String(16), nullable=False)


class Forum(Base):
    __tablename__ = 'forum'

    id = Column(Integer, primary_key=True)
    name = Column(String(200), nullable=False)
    collectors = relationship(  # 模型类关系
        'User',  # 引用的模型类
        secondary=user_forum_collection, # 中间表
        backref=backref('collect_forums', lazy='dynamic'), # 反向引用关系与反向懒加载
        lazy='dynamic', # 正向懒加载
    )

2 中间表解释

需要新导入的包:

from sqlalchemy import Table
  • 中间表一般不采用Class的方式来定义,而使用Table
  • Column中第一参数是列明,而不是类型了
    • Column(‘id’, Integer, primary_key=True, autoincrement=True)
  • 中间表如果定义主键的话,除了primary_key=True,还必须加上autoincrement=True,否则保存
  • 外键引用,其实也可以加上primary_key=True(官方爱这么写,我觉得不加也行)
    • 例如:Column(‘user_id’, Integer, ForeignKey(‘user.id’),primary_key=True)

3 relationship关系维护

  • secondary=中间表
  • 如果有中间表的话,最好定义正向和反向都是懒加载,即lazy=‘dynamic’

猜你喜欢

转载自blog.csdn.net/kzl_knight/article/details/103108785
今日推荐