SQLAlchemy: как правильно использовать Relationship()?

#python

#python

Вопрос:

Я просмотрел документы и думаю, что все правильно структурировал, но изо всех сил пытаюсь это реализовать.

В этом есть две части: вариант использования — когда я смотрю на резюме, в каждом резюме есть несколько заданий. Тогда сумма всех этих заданий определяет ценность всего резюме.

Я настроил две таблицы и соответствующие классы.

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

Base = declarative_base()
engine = create_engine('sqlite:///candidate.db', echo=True)


class Candidate_Evaluation(Base):
    __tablename__ = 'candidate_evaluation'
    id = Column(Integer, primary_key=True)
    label = Column(String)
    url = Column(String)
    string_of_job_evals = Column(String)
    job_evaluation_relationship = relationship("Job_Evaluation", back_populates="candidate_evalution")
    def __repr__(self):
        "<Candidate(URL = '%s', label = '%s', job evaluations = '%s')>" % (self.url, self.label, self.string_of_job_evals)


class Job_Evaluation(Base):
    __tablename__ = 'job_evaluation'
    id = Column(Integer, primary_key=True)
    candidate_evaluation_id = Column(Integer, ForeignKey('candidate_evaluation.id')) #
    details = Column(String)
    label = Column(String)
    candidate_evaluation_relationship = relationship("Candidate_Evaluation", back_populates='job_evaluation')
    def __repr__(self):
        "<Job(label = '%s', details = '%s')>" %(self.label, self.details)


Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

job = Job_Evaluation(label = 'front_end', details = 'javascript jquery html css')
session.add(job)
session.commit()
  

Однако я сталкиваюсь с проблемой, когда пытаюсь добавить записи в job_evaluation таблицу. Я думаю, это связано с тем, как я установил отношения между ними.

Цель состоит в том, чтобы я мог добавить оценку задания в базу данных, а затем связать ее с оценкой кандидата. Это отношение «Многие к одному», но «Многие» на первом месте. Возможно ли это?

Я получаю сообщение об ошибке:

sqlalchemy.exc.InvalidRequestError: Mapper 'Mapper|Job_Evaluation|job_evaluation' has no property 'candidate_evalution'

Что я делаю не так?

Комментарии:

1. Свойство класса candidate_evaluation_relationship равно candidate_evaluation not , поэтому либо измените relationship(..., back_populates="candidate_evalution_relationship") его, либо переименуйте.

2. Ах, упс. внес это изменение, не осознавая этого. Спасибо!

Ответ №1:

Я боролся с этим в первые дни использования sqlalchemy.

Как указано в документах:

Принимает строковое имя и имеет то же значение, что и backref , за исключением того, что дополняющее свойство не создается автоматически, а вместо этого должно быть явно настроено на другом mapper . Дополняющее свойство также должно указывать back_populates для этого отношения, чтобы обеспечить надлежащее функционирование.

 class Candidate_Evaluation(Base):
    __tablename__ = 'candidate_evaluation'
    id = Column(Integer, primary_key=True)
    label = Column(String)
    url = Column(String)
    string_of_job_evals = Column(String)
    job_evaluation_relationship = relationship("Job_Evaluation", backref ="candidate_evalution")
    def __repr__(self):
        "<Candidate(URL = '%s', label = '%s', job evaluations = '%s')>" % (self.url, self.label, self.string_of_job_evals)


class Job_Evaluation(Base):
    __tablename__ = 'job_evaluation'
    id = Column(Integer, primary_key=True)
    candidate_evaluation_id = Column(Integer, ForeignKey('candidate_evaluation.id')) #
    details = Column(String)
    label = Column(String)
    candidate_evaluation_relationship = relationship("Candidate_Evaluation", backref = job_evaluation')
    def __repr__(self):
        "<Job(label = '%s', details = '%s')>" %(self.label, self.details)
  

Просто замените back_populates на backref .

Комментарии:

1. для тех, кто изучает все с нуля, читая только документацию, это также может быть написано на китайском языке: (

2. Я чувствую твою боль. Это становится лучше, я обещаю 🙂