marshmallow-sqlalchemy icon indicating copy to clipboard operation
marshmallow-sqlalchemy copied to clipboard

AssertionError: Dependency rule tried to blank-out primary key column

Open manc1 opened this issue 5 years ago • 4 comments

Hello, I have a problem with nested that have a foreign key which is also a primary key. What I'm trying to accomplish is extremely simple.


Base: Any = declarative_base()
Session: Any = orm.scoped_session(orm.sessionmaker())

class Author(Base):
    __tablename__="authors"
    name = Column(String, primary_key=True)
    desc = Column(String, nullable=False)
    book_id = Column(Integer, ForeignKey("books.book_id"), primary_key=True)


class AuthorSchema(ModelSchema):

    class Meta:
        model = Author
        sqla_session = Session


class Book(Base):
    __tablename__ = "books"
    book_id = Column(Integer, primary_key=True)
    authors = relationship("Author", backref="book")


class BookSchema(ModelSchema):
    authors = fields.Nested(AuthorSchema, many=True)

    class Meta:
        model = Book
        sqla_session = Session

This is quite straightforward. I would like to have a book instance linked to multiple authors. Then, suppose I loads a JSON ponting to an existent book instance and suppose I would like to change desc value of an author. I then commit the change and get an AssertionError. Let`s see the code:

    engine = create_engine("postgresql://localhost", echo=False)
    Base.metadata.create_all(engine)
    Session.configure(bind=engine)
    session = Session()
    book = Book(book_id=6934389)
    author1 = Author(name="myname", desc='mydesc')
    book.authors = [author1]
    session.add(book)
    session.commit()
    schema = BookSchema()
    json_book = schema.dumps(book)
    schema = BookSchema()
    book = schema.loads(json_book)
    book.authors[0].desc = 'newdesc'
    session.add(book)
    session.commit()
    session.close()

Result

Traceback (most recent call last):
  File "/models/db_models.py", line 264, in <module>
    session.commit()
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 1027, in commit
    self.transaction.commit()
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 494, in commit
    self._prepare_impl()
  File ".venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 473, in _prepare_impl
    self.session.flush()
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2459, in flush
    self._flush(objects)
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2597, in _flush
    transaction.rollback(_capture_exception=True)
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 153, in reraise
    raise value
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/session.py", line 2557, in _flush
    flush_context.execute()
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 422, in execute
    rec.execute(self)
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/unitofwork.py", line 540, in execute
    self.dependency_processor.process_saves(uow, states)
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/dependency.py", line 584, in process_saves
    state, child, None, True, uowcommit, False
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/dependency.py", line 604, in _synchronize
    sync.clear(dest, self.mapper, self.prop.synchronize_pairs)
  File "/.venv/lib/python3.7/site-packages/sqlalchemy/orm/sync.py", line 87, in clear
    "column '%s' on instance '%s'" % (r, orm_util.state_str(dest))
AssertionError: Dependency rule tried to blank-out primary key column 'authors.book_id' on instance '<Author at 0x10f9a3190>'

Any idea of how can I solve this?

Thank you very much!

manc1 avatar Sep 06 '19 15:09 manc1

I have the same error: "AssertionError: Dependency rule tried to blank-out primary key column", while loading a json data for an existing object. The error doesn't even occur when doing a session.add / session.merge, but directly when an autoflush is generated inside the load. The object whose primary key is being deleted is present in the json, so I guess the autoflush is generated for a partial data. Anyway it makes no sense to try to wipe the primary key (juste like your example). Especially as it's just in the load. It's very annoying.

eino avatar Dec 13 '19 12:12 eino

i get the same error, any news on this? 👀

giovanni-bellini-argo avatar Apr 17 '24 09:04 giovanni-bellini-argo