【问题标题】:Many to Many relationships with unique values in a junction table联结表中具有唯一值的多对多关系
【发布时间】:2021-09-07 07:50:09
【问题描述】:

我一直在尝试使用 Flask 构建网站,但在为数据库提出合适的模型时遇到了一些问题。我正在制作一个功能类似于读书俱乐部的应用程序。

以下是提出模型的详细信息:

  1. 一个用户可以添加多本书
  2. 一本书可供多个用户阅读
  3. 每个用户都必须为每本书添加一个(并且只有一个)状态标签(表示已读、待读或正在阅读)

我正在努力为此想出一个合适的模型。我正在使用flask-sqlalchemy。

这是我目前所拥有的:

class User(db.Model):
    id = db.Column(db.String, default = urlsafe_b64encode(uuid().bytes)[0:10], primary_key=True) #unique id
    username = db.Column(db.String(20), unique=True, nullable=False)
    password = db.Column(db.String(80), unique=True, nullable=False)
    firstName = db.Column(db.String(20), unique=True, nullable=False)
    bookstatus = db.relationship('BookStatus', backref='user', lazy=True)
    date_created = db.Column(db.DateTime, default=datetime.now)

class BookStatus(db.Model):
    book_id = db.Column(db.Integer, db.ForeignKey('book.id'), primary_key=True)
    added_by = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    status = db.Column(db.Integer, nullable=False)
    
class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    gbook_id = db.Column(db.String(20), unique=False, nullable=False)
    added_by = db.Column(db.String, db.ForeignKey('user.id'),
        nullable=False)
    bookstatus = db.relationship("BookStatus", backref='book', lazy=True)

有人告诉我,这本书的多对多关系的联结表应该定义为一个表,而不是通过一个类,但我不确定如何包含状态列。然后我是否对表和 bookstatus 类使用一对一的关系?还是我完全错了!!

请帮忙!我一直在努力解决这个问题。

谢谢!

【问题讨论】:

    标签: database sqlite flask model flask-sqlalchemy


    【解决方案1】:

    多对多关系由BookStatus模型和数据库中对应的表来表示。 所以这里是你的模型:

    class User(db.Model):
        __tablename__ = 'user'
        id = db.Column(db.String, default = urlsafe_b64encode(uuid().bytes)[0:10], primary_key=True) #unique id
        username = db.Column(db.String(20), unique=True, nullable=False)
        password = db.Column(db.String(80), unique=True, nullable=False)
        firstName = db.Column(db.String(20), unique=True, nullable=False)
        date_created = db.Column(db.DateTime, default=datetime.now)
    
    class BookStatus(db.Model):
        __tablename__ = 'book_status'
        book_id = db.Column(db.Integer, db.ForeignKey('book.id'), primary_key=True)
        added_by = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
        status = db.Column(db.Enum('read', 'to be read', 'being read'), nullable=False)
    
        user = db.relationship('User', foreign_keys=[added_by])
        book = db.relationship('Book', foreign_keys=[book_id])
        
    class Book(db.Model):
        __tablename__ = 'book'
        id = db.Column(db.Integer, primary_key=True)
        gbook_id = db.Column(db.String(20), unique=False, nullable=False)
    

    我已将您的 BookStatus.status 属性更改为枚举类型。可以使用 Integer,例如 0(正在读取)、1(待读取)和 2(已读取),但我认为在这种情况下使用 enum 类型更好。

    在 ORM(对象-关系映射)和关系数据库设计中,每个实体(对象、表)只需要具有可以描述该实体的属性。例如 Book. added_by 不能,或者更准确地说不应该表示为书籍的属性。 User.book_status 也有同样的情况。用户不是一本书。

    图书作为属性的状态需要是图书实体的属性(如果该状态代表图书的质量)。在您的情况下,book_status 与联结表(实体)相关 - BookStatus(用户和图书之间的多对多关系)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-11
      • 2016-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-29
      • 2016-08-21
      • 1970-01-01
      相关资源
      最近更新 更多