SQLAlchemy - Как создать отношения один ко многим без элементов? - PullRequest
1 голос
/ 23 января 2020

Я пытаюсь создать объект в SQLAlchemy, который может иметь связь со многими элементами, но не обязан. Вот мой файл моделей:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import Column, String, Integer, ForeignKey

Base = declarative_base()

class Media(Base):

    __tablename__ = "media"
    id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
    video_id = Column(String)
    audio = relationship("audio", back_populates="media")

class Audio(Base):

    __tablename__ = "audio"
    id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
    media_id = Column(Integer, ForeignKey("media.id"))
    media = relationship("Media", back_populates="audio")

Это создает отношение «один ко многим» от медиа до аудио. Однако, когда я пытаюсь создать элемент мультимедиа, используя [] или None в качестве параметра, происходит ошибка. Вот что я делаю:

new_media_item = Media(
    video_id = some_video_id,
    audio = None # i've also tried [] or just not specifying audio
)

Но я получаю эту ошибку:

Traceback (most recent call last):
  --- some cli code, snipped ---
  File "cool_program.py", line 30, in do_add_media
    audio = None
  File "<string>", line 2, in __init__
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/instrumentation.py", line 376, in _new_state_if_none
    state = self._state_constructor(instance, self)
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 855, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/instrumentation.py", line 202, in _state_constructor
    self.dispatch.first_init(self, self.class_)
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/event/attr.py", line 322, in __call__
    fn(*args, **kw)
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/mapper.py", line 3361, in _event_on_first_init
    configure_mappers()
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/mapper.py", line 3249, in configure_mappers
    mapper._post_configure_properties()
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/mapper.py", line 1947, in _post_configure_properties
    prop.init()
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/interfaces.py", line 196, in init
    self.do_init()
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/relationships.py", line 1914, in do_init
    self._process_dependent_arguments()
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/relationships.py", line 1976, in _process_dependent_arguments
    self.target = self.entity.persist_selectable
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 855, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/home/spazzlo/.local/lib/python3.6/site-packages/sqlalchemy/orm/relationships.py", line 1899, in entity
    % (self.key, type(argument))
sqlalchemy.exc.ArgumentError: relationship 'audio' expects a class or a mapper argument (received: <class 'sqlalchemy.sql.schema.Table'>)

1 Ответ

2 голосов
/ 24 января 2020

Вы должны указать имя класса, а не имя таблицы в отношении:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import Column, String, Integer, ForeignKey

Base = declarative_base()

class Media(Base):

    __tablename__ = "media"
    id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
    video_id = Column(String)
    audio = relationship("Audio", back_populates="media")  # changed 'audio' to 'Audio'

class Audio(Base):

    __tablename__ = "audio"
    id = Column(Integer, primary_key=True, unique=True, autoincrement=True)
    media_id = Column(Integer, ForeignKey("media.id"), nullable=True)
    media = relationship("Media", back_populates="audio")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...