1

如果我有两个表:A(id,...其他一些列)和 B(id,...一些其他列)。我需要将 Comments(另一个表:id、text、author)与 A 和 B 对象相关联。

我可以为此目的创建第四个表:comment_id、table_id(A 或 B 或其他)、item_id 吗?我的意思是一些 sqlalchemy 方式?

现在我只知道这两个解决方案: http: //bpaste.net/show/27149/ - 对于每个 A 和 B,将有单独的表格和注释。我认为这不是一个好主意,因为这些表(应该)是相同的,如果我想查看某个作者的所有评论 - 如果有一天会有 C 表,这将比其他方式更困难 - 我将需要为其评论创建一个表格...

另一种解决方案 - http://bpaste.net/show/27148/。我认为更好,但我仍然需要为我需要评论项目的每个表创建一个关联表。

有任何想法吗?提前致谢。

4

2 回答 2

2

你可以试试:

class Comment(Base):
    __tablename__ = 'comments'

    id = Column(Integer, primary_key=True)
    a_id = Column(Integer, ForeignKey('a.id'), nullable=True)
    b_id = Column(Integer, ForeignKey('b.id'), nullable=True)
    text = Column(UnicodeText, nullable=False)

    def __init__(self, text):
        self.text = text

它仍然是一种比较老套的方法,但它通过使用外键来保持引用完整性。

如果您想寻找存储表名的解决方案,您可以尝试以下方法:

class A(Base):
    __tablename__ = 'as'

    id = Column(Integer, primary_key=True)
    name = Column(Unicode, nullable=False, unique=True)
    comments = relationship("Comment",
                    primaryjoin="and_(A.id==Comment.id, "
                        "Comment.model=='A')")

    def __init__(self, name):
        self.name = name

class Comment(Base):
    __tablename__ = 'comments'

    id = Column(Integer, primary_key=True)
    text = Column(UnicodeText, nullable=False)
    model = Column(String(50), nullable=False)

    def __init__(self, text):
        self.text = text

我自己没有对此进行测试,因此如果您遇到问题,请查看指定备用连接条件或评论,我会做更多的研究。

有关该主题的深入解释,请参阅Mike Bayer 关于多态关联的博客条目

于 2012-04-16T15:06:45.937 回答
0

我也会选择第二种解决方案。但是,正如您所说,可能会有第三个表C,那么您可以将B_CommentandA_Comment作为字段放在一个关联表中,例如:

class Comment(Base):
    id = Column(Integer, primary_key=True)
    a_id = Column(Integer, ForeignKey('as.id'), primary_key=True, nullable=True)
    b_id = Column(Integer, ForeignKey('bs.id'), primary_key=True, nullable=True)
    text = Column(UnicodeText, nullable=False)
    # ...

您将使用如下查询:session.query(Comment).filter_by(a=whatever)

我想你可以添加某种约束,这样a_idb_id不是同时的NULL

这是另一种方法(我不知道这是否是标准方法,但它应该可以工作......

class Letter(Base):
    id = ...

class A(Base):
    letter_id = Column(Integer, ForeignKey('letters.id'), primary_key=True, nullable=False)
    # ...

class Comment(Base):
    letter_id = Column(Integer, ForeignKey('letters.id'), primary_key=True, nullable=True)
    # ...
于 2012-04-16T15:18:00.693 回答