-
Notifications
You must be signed in to change notification settings - Fork 98
I suspect a breaking change related to "include_relationships=True" and schema.load() in version 1.4.1 #664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I wasn't able to reproduce this. added a test to cover this case in #666 and it passes. @Curiouspaul1 can you post a more complete minimal reproducible example? |
Hi @sloria That's strange, are you sure you tested with a
I had to create a simple test to reproduce behavior outside of the running application, so it's pretty basic steps to reproduce. All i'm doing is using a sqlalchemyautoschema instance to dump a sqlalchemy instance, as described above: # user model
class User(db.Model):
# .. define columns ..
address = db.relationship('Address', backref='user')
class UserSchema(Base):
class Meta:
model = User
include_relationships=True # includes for example an 'address' relationship attr (could be something like a 'backref' or explicitly declared field on the sqlalchemy model)
include_fk = True
load_instance = True
# usage and expected behavior
schema = UserSchema(unknown='exclude', session=session)
user = schema.load(**data)
# returns <User> object
# Observed behavior
# .. same steps
# throws 'Missing data for required 'address' field - error' PS: The User nd Address example aren't exactly the same models in our usecase, but its representative of what exactly is happening. Here's a snippet of the error i'm getting:
So as you can see, the Hopefully this helps. |
@sloria any update on this? |
sorry--haven't had much time to work on marshmallow these days. would definitely appreciate help on this, even if it's an incomplete PR. |
I am currently working on updating app dependencies and came across this issue. After some digging into my problem, which may not be exactly the same, I think this PR could be the breaking change. In my use case, we had defined a Prior to that commit, with models and schemas setup like: class User(db.Model):
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
friends = relationship(UserFriend, back_populates='user')
class UserFriend(db.Model):
user_id = ForeignKey(User.id, nullable=False)
name = Column(String, nullable=False)
user = relationship(User, back_populates='friends')
class UserFriendSchema(SQLAlchemyAutoSchema):
class Meta:
model = UserFriend
include_relationships = True
load_instance = True
class UserSchema(SQLAlchemyAutoSchema):
class Meta:
model = User
include_relationships = True
load_instance = True
friends = Nested(UserFriendSchema, many=True) This was possible: user_data = {'name': 'Bob', 'friends': ['name': 'Joe', 'name': 'Tom']}
new_user, errors = UserSchema.load(user_data, instance=None)
assert not errors
db.session.add(new_user)
db.session.commit()
assert new_user.name == 'Bob'
assert sorted([f.name for f in new_user.friends]) == ['Joe', 'Tom'] After that commit, this is the result: user_data = {'name': 'Bob', 'friends': ['name': 'Joe', 'name': 'Tom']}
new_user, errors = UserSchema.load(user_data, instance=None)
# errors == {
# 'friends': {
# 0: {'user': ['Missing data for required field.']},
# 1: {'user': ['Missing data for required field.']},
# } Since this is an I did notice that by removing the defined
which I have determined is caused by the fact that on line 133 of fields.py def _get_existing_instance(self, related_model, value):
...
else:
# Use a faster path if the related key is the primary key.
lookup_values = [value.get(prop.key) for prop in self.related_keys]
# When lookup_values == [None], there is no primary_key data, so no need to call session.get
# Otherwise, SAWarning: fully NULL primary key identity cannot load any object will be raised
if len(lookup_values) == 1 and lookup_values[0] is None:
raise NoResultFound
try:
result = self.session.get(related_model, lookup_values)
except TypeError as error:
keys = [prop.key for prop in self.related_keys]
raise self.make_error("invalid", value=value, keys=keys) from error
if result is None:
raise NoResultFound
return result Unfortunately, in my case, right now I think I need a |
Hi ! I recently had to do some testing on my local for some portion of our code that's been running happily on staging. I didn't specify a version number for my local container instance, as such it pulled
1.4.1
which is the latest. I noticed that it seems to enforce implicitly defined fields (from the include_relationships=True option), during aschema.load()
which I THINK isn't the desired or USUAL behavior.Typically (in previous versions specifically 1.1.0 ) we've been able to deserialize into objects with schemas defined with the
include_relationships
option set to True - without having to provide values for relationship fields (which intuitively makes sense), however for some reason it's raising a Validation (Missing field) error on1.4.1
. This behavior wasn't reproducable on1.1.0
(not that I would know if this is on later versions in:1.1.0 < version < 1.4.1
because we've not used any other up until my recent local testing which used1.4.1
).The text was updated successfully, but these errors were encountered: