Unknown field error on foreign key : cannot validate the marshmallow schemas of two SQLAlchemy in a Many-to-One relationship
See original GitHub issueI have got two SQLAlchemy
objects as follow:
- an object
Person
with astring
name
that acts as a primary key. - an object
Submission
with a simpleid
primary key and a fieldrequester_name
In other words one person
can make many submission
, this is a many-to-one
relationship, that I have set up exactly like in the sqlalchemy doc.
I can manipulate the code SQLAlchemy
side without any problems, and when I dump
the two schemas
throughs marshmallow
, I get the expected result.
But My issue is an unknown_field
error on the foreign key when I try to validate
the schema of the parent object.
Here is the code:
# tests
from pprint import pprint
from sqlalchemy import Column, ForeignKey, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
from marshmallow import ValidationError
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
# sqlalchemy
Base = declarative_base()
engine = create_engine("sqlite:///:memory:")
session = sessionmaker(bind=engine)()
class Person(Base):
__tablename__ = "persons"
name = Column(String(64), primary_key=True)
# MANY-TO-ONE. One Person can make many Submission
class Submission(Base):
__tablename__ = "submissions"
id = Column(Integer, primary_key=True)
requester_name = Column(String(64), ForeignKey("persons.name"))
requester = relationship("Person")
Base.metadata.create_all(engine)
# marshmallow
class PersonSchema(SQLAlchemyAutoSchema):
class Meta:
model = Person
load_instance = True
class SubmissionSchema(SQLAlchemyAutoSchema):
class Meta:
model = Submission
load_instance = True
requester = fields.Nested(PersonSchema)
def test_person():#SUCCESS
try:
PersonSchema().load({"name": "Maria"}, session=session)
assert True
except ValidationError as err:
pprint(err.messages)
assert False
def test_submission():#FAILURE
try:
SubmissionSchema().load({"requester_name": "Maria"}, session=session)
assert True
except ValidationError as err:
pprint(err.messages)
assert False
Here is the raised ValidationError
:
marshmallow.exceptions.ValidationError: {'requester_name': ['Unknown field.']}
Obviously the field is there (shows in the console, if I insert the object in the database, it’s there, etc.) and I don’t understand why thre’s an error like that.
I would appreciate any help.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
SQLAlchemy + Marshmallow 'Unknown field.' error in a Many ...
For two objects in a many-to-one relationship, the validation fails because supposedly one of the fields of the parent is unknown, desptie being ......
Read more >marshmallow-sqlalchemy - Read the Docs
SQLAlchemy has a hook that can be used to trigger the creation of the schemas, assigning them to the SQLAlchemy model property Model.__ ......
Read more >Python REST APIs With Flask, Connexion, and SQLAlchemy
Create one-to-many fields in your database; Manage relationships with SQLAlchemy; Leverage nested schemas with Marshmallow; Display related ...
Read more >Nesting Schemas — marshmallow 3.19.0 documentation
Schemas can be nested to represent relationships between objects (e.g. foreign key relationships). For example, a Blog may have an author represented by...
Read more >sqlalchemy/community - Gitter
How can I take care of the foreign key when inserting new data. ... I have 2 tables with ManyToMany relationship which is...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
By default the auto-generated schemas exclude foreign key fields:
https://github.com/marshmallow-code/marshmallow-sqlalchemy/blob/3d02bbb15d43e2e4c65039694faa8a73278c4006/src/marshmallow_sqlalchemy/schema/sqlalchemy_schema.py#L67-L72
If you add
include_fk = True
toSubmissionSchema.Meta
your example will run.They do different things. One serializes a column property, the other serializes a relationship property. I’ll try to demonstrate why they should be independent of eachother.
Given
SubmissionSchema
defined like this:Serializing a submission would look like this:
… where the key
requester
represents the relationship,requester_name
the foreign key and they both present the same information.From the
Person
side, say we add asubmissions
relationship toPerson
:Adding
include_fk=True
toPersonSchema
in this case will do nothing as there are no FKs, however addinginclude_relationships=True
we get:I can’t see it mentioned in the docs anywhere but
include_relationships=True
creates aRelated
field to represent the relationship and then wraps it in aRelatedList
if it is a “many” side. The default behavior ofRelated
is to use the primary key in a “flattened” representation of the related instances.If your models looked like this:
And the
SubmissionSchema
:Then serializing the submission:
Not a very helpful representation, so I’ll change
SubmissionSchema
to present more info about therequester
:Now serializing the submission returns:
Now that I’ve got a nested object representation of the
requester
, I might decide that it is redundant to also have therequester_id
in the enclosing scope, so I’ll removeinclude_fk=True
from the schema as well which then serializes the submission to: