【问题标题】:Can't map Many-to-Many relationship in SQLAlchemy无法在 SQLAlchemy 中映射多对多关系
【发布时间】:2018-02-05 15:17:10
【问题描述】:

我有两个对象,UserRoom,它们都继承自 Base 对象。

class BaseModel:
    __metaclass__ = Serializable

    created = Column(DateTime, default=func.now())
    modified = Column(DateTime, default=func.now(), onupdate=func.now())

    @declared_attr
    def __tablename__(self):
        return self.__name__.lower()


Base = declarative_base(cls=BaseModel)

这是我的 User 模型,其中声明了与 Room 的多对多关联。

association_table = Table('users_rooms', Base.metadata,
    Column('user_id', Integer, ForeignKey('user.id')),
    Column('room_id', Integer, ForeignKey('room.id'))
)
class User(Base):
    __table_args__ = {'extend_existing': True}

    id = Column(Integer, primary_key=True)
    mobile = Column(String(20), index=True, unique=True)
    rooms = relationship("Room", secondary=association_table, 
    back_populates="users")

这就是房间模型。

association_table = Table('users_rooms', Base.metadata,
                          Column('user_id', Integer, ForeignKey('user.id')),
                          Column('room_id', Integer, ForeignKey('room.id'))
                          )


class Room(Base):

    __table_args__ = {'extend_existing': True}

    id = Column(Integer, primary_key=True)
    room_type = Column(String(50), default=RoomType.PRIVATE)
    hex_code = Column(String(100), unique=True)
     users = relationship("User", secondary=association_table, back_populates="rooms")

当我尝试编译它时,我收到以下错误。

sqlalchemy.exc.InvalidRequestError: Table 'users_rooms' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

【问题讨论】:

    标签: python orm sqlalchemy


    【解决方案1】:

    该错误试图告诉您不需要——也不应该——在两个模块中定义关联表。在其中一个或自己的模块中定义它,然后导入它,或者在 relationship() 中使用 secondary="users_rooms" 懒惰地引用它:

    # Room model. Note the absence of `association_table`
    
    class Room(Base):
    
        id = Column(Integer, primary_key=True)
        room_type = Column(String(50), default=RoomType.PRIVATE)
        hex_code = Column(String(100), unique=True)
        users = relationship("User", secondary="users_rooms", back_populates="rooms")
    

    secondary= 中传递的作为字符串值的表名是从与Room 模型关联的MetaData 集合中查找的。​​p>

    你也应该不需要洒

    __table_args__ = {'extend_existing': True}
    

    在您的模型中。如果您在没有它的情况下遇到类似于此问题中的错误,则在构建模型之前,这些表已经创建并包含在 MetaData 集合中。例如,您可能使用过反射。

    【讨论】:

    • 工作就像一个魅力。
    猜你喜欢
    • 2019-04-07
    • 2011-01-19
    • 2020-09-18
    • 2014-08-17
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多