如何在 SQLAlchemy 中创建一个包含外键列表的字段?

How to create a field with a list of foreign keys in SQLAlchemy?

我正在尝试在另一个模型的字段中存储模型列表。下面是一个简单的示例,我有一个现有模型 Actor,我想创建一个新模型 Movie,字段为 Movie.list_of_actors:

import uuid

from sqlalchemy import Boolean, Column, Integer, String, DateTime
from sqlalchemy.schema import ForeignKey
rom sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

Base = declarative_base()


class Actor(Base):
    __tablename__ = 'actors'

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String)
    nickname = Column(String)
    academy_awards = Column(Integer)


# This is my new model:
class Movie(Base):
    __tablename__ = 'movies'

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    title = Column(String)
    # How do I make this a list of foreign keys???
    list_of_actors = Column(UUID(as_uuid=True), ForeignKey('actors.id'))

我知道这可以通过多对多关系来完成,但是有没有更简单的解决方案? 请注意,我不需要查找 Movie 中的哪个 Actor - 我只想创建一个新的 Movie 模型并访问我的 Actor 的列表。理想情况下,我不希望向我的 Actor 模型添加任何新字段。

我已经使用 relationships API, which outlines the various one-to-many/many-to-many combinations using back_propagates and backref here: http://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html 完成了教程,但是如果不创建一个成熟的多对多实现,我似乎无法实现我的外键列表。

但是如果多对多实现是唯一的继续进行的方式,是否有一种无需创建 "association table" 即可实现的方法? "association table" 在这里描述:http://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#many-to-many ?无论哪种方式,一个示例都会非常有帮助!


此外,如果重要的话,我使用的是 Postgres 9.5。我从 this post 了解到 Postgres 中可能支持数组,因此对此的任何想法都会有所帮助。

更新

看起来这里唯一合理的方法是创建关联 table,如下面的所选答案所示。我尝试使用 ARRAY from SQLAlchemy's Postgres Dialect 但它似乎不支持外键。在上面的示例中,我使用了以下列:

list_of_actors = Column('actors', postgresql.ARRAY(ForeignKey('actors.id')))

但它给了我一个错误。似乎对带有外键的 Postgres ARRAY 的支持正在进行中,但还不完全存在。这是我找到的最新信息来源:http://blog.2ndquadrant.com/postgresql-9-3-development-array-element-foreign-keys/

如果您希望许多演员与一部电影相关联,并且许多电影与一个演员相关联,您需要多对多。这意味着您需要一个关联 table。否则,您可以放弃规范化并使用 NoSQL 数据库。

关联 table 解决方案可能类似于:

class Actor(Base):
    __tablename__ = 'actors'

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String)
    nickname = Column(String)
    academy_awards = Column(Integer)

class Movie(Base):
    __tablename__ = 'movies'

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    title = Column(String)

    actors = relationship('ActorMovie', uselist=True, backref='movies')

class ActorMovie(Base):
    __tablename__ = 'actor_movies'

    actor_id = Column(UUID(as_uuid=True), ForeignKey('actors.id'))
    movie_id = Column(UUID(as_uuid=True), ForeignKey('movies.id'))

如果您不想让 ActorMovie 成为继承自 Base 的对象,您可以使用 sqlachlemy.schema.Table.