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

Meta option include_fk is ignored if set to True anywhere in the schema's MRO

Open uhnomoli opened this issue 3 years ago • 2 comments

Once include_fk is set to True anywhere in the MRO of a schema, it cannot be disabled. As a workaround, it can be excluded (e.g. exclude = ('author_id',)).

Minimal reproducible example:

from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref

engine = sa.create_engine("sqlite:///:memory:")
session = scoped_session(sessionmaker(bind=engine))
Base = declarative_base()

class Author(Base):
    __tablename__ = "authors"
    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.String, nullable=False)

    def __repr__(self):
        return "<Author(name={self.name!r})>".format(self=self)

class Book(Base):
    __tablename__ = "books"
    id = sa.Column(sa.Integer, primary_key=True)
    title = sa.Column(sa.String)
    author_id = sa.Column(sa.Integer, sa.ForeignKey("authors.id"))
    author = relationship("Author", backref=backref("books"))

Base.metadata.create_all(engine)

class AuthorSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = Author
        include_relationships = True
        load_instance = True

class BookSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = Book
        include_fk = True
        load_instance = True

class BookNoFKSchema(BookSchema):
    class Meta(BookSchema.Meta):
        include_fk = False

class BookExcludeFKSchema(BookSchema):
    class Meta(BookSchema.Meta):
        exclude = ('author_id',)

author = Author(name="Chuck Paluhniuk")
book = Book(title="Fight Club", author=author)
session.add(author)
session.add(book)
session.commit()

print(BookSchema().dump(book))
# {'title': 'Fight Club', 'author_id': 1, 'id': 1}

print(BookNoFKSchema().dump(book))
# {'title': 'Fight Club', 'author_id': 1, 'id': 1}

print(BookExcludeFKSchema().dump(book))
# {'title': 'Fight Club', 'id': 1}

uhnomoli avatar Jun 10 '22 21:06 uhnomoli

Thanks for reporting. This look like a bug, indeed.

lafrech avatar Jun 13 '22 07:06 lafrech

@lafrech @Anomareh I ran into the same issue and thought I created a PR for a potential fix. The main issue is that get_declared_fields does not really differentiate between fields and inherited_fields so the information surrounding which fields have been added by include_fk is lost when inheriting.

jonasps avatar Jul 29 '22 22:07 jonasps