sqlaclemy back_populates не заполняет поле идентификатора

#python #sqlalchemy

#python #sqlalchemy

Вопрос:

У меня есть две модели, определенные с помощью sqlalchemy, которые имеют взаимно однозначное отношение. Упрощая вещи, это будет выглядеть примерно так:

 class First(Base):
    __tablename__ = "first"
    id = Column(Integer, primary_key=True)
    second_id = Column(Integer, ForeignKey("second.id"))
    second = relationship("Second", uselist=False, back_populates="first")


class Second(Base):
    __tablename__ = 'second'
    id = Column(Integer, primary_key=True)
    first_id = Column(Integer, ForeignKey("first.id"))
    first = relationship("First", uselist=False, back_populates="second")
 

Когда я пытаюсь добавить второй объект к существующему первому, я получаю сообщение об ошибке:

 first = First(id=1)
session.add(first)
session.commit()

second = Second(first=first)
session.add(second)
session.commit()

>>> Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2243, in flush
    self._flush(objects)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2369, in _flush
    transaction.rollback(_capture_exception=True)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 2333, in _flush
    flush_context.execute()
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 391, in execute
    rec.execute(self)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 556, in execute
    uow
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py", line 181, in save_obj
    mapper, table, insert)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py", line 866, in _emit_insert_statements
    execute(statement, params)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
    context)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
    exc_info
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/home/mhodis/.virtualenvs/project/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 507, in do_execute
    cursor.execute(statement, parameters)
IntegrityError: (psycopg2.IntegrityError) null value in column "first_id" violates not-null constraint
DETAIL:  Failing row contains (1, null).
 [SQL: 'INSERT INTO second (first_id) VALUES (%(first_id)s RETURNING second.id'] [parameters: {'first': None}] (Background on this error at: http://sqlalche.me/e/gkpj)
 

Насколько я понимаю, back_populates должен обрабатывать присвоение идентификаторов, если мы устанавливаем object в поле relational. Что здесь не так?

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

1. Этот код вызывает AmbiguousForeignKeyError при выполнении.