marshmallow-sqlalchemy
marshmallow-sqlalchemy copied to clipboard
Meta option include_fk is ignored if set to True anywhere in the schema's MRO
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}
Thanks for reporting. This look like a bug, indeed.
@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.