From 93c409054c9b574387f660c39f23451c5a101ba5 Mon Sep 17 00:00:00 2001 From: indivar Date: Sun, 4 Sep 2022 10:23:08 +0530 Subject: [PATCH] fix #336: detecting relationship as nullable=False --- src/marshmallow_sqlalchemy/convert.py | 2 +- tests/conftest.py | 2 +- tests/test_conversion.py | 43 +++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/marshmallow_sqlalchemy/convert.py b/src/marshmallow_sqlalchemy/convert.py index fa97ebf9..552e82c0 100644 --- a/src/marshmallow_sqlalchemy/convert.py +++ b/src/marshmallow_sqlalchemy/convert.py @@ -349,7 +349,7 @@ def _add_relationship_kwargs(self, kwargs, prop): nullable = True for pair in prop.local_remote_pairs: if not pair[0].nullable: - if prop.uselist is True: + if prop.uselist is True or prop.direction.name == "MANYTOONE": nullable = False break kwargs.update({"allow_none": nullable, "required": not nullable}) diff --git a/tests/conftest.py b/tests/conftest.py index 51e237d7..ae0881d7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -194,7 +194,7 @@ class Lecture(Base): seminar = relationship( Seminar, foreign_keys=[seminar_title, seminar_semester], backref="lectures" ) - kw = relationship("Keyword", secondary=lecturekeywords_table) + kw = relationship("Keyword", uselist=False, secondary=lecturekeywords_table) keywords = association_proxy( "kw", "keyword", creator=lambda kw: Keyword(keyword=kw) ) diff --git a/tests/test_conversion.py b/tests/test_conversion.py index 6059a6bc..5bde1b2b 100644 --- a/tests/test_conversion.py +++ b/tests/test_conversion.py @@ -354,6 +354,49 @@ class ModelWithArray(Base): assert field.dump_only is True +class TestRelationshipKwarg: + def test_many_to_one_relationship_kwarg(self, models): + default_converter = ModelConverter() + + rel = models.Student.__mapper__.attrs.get("current_school") + assert rel.direction.name == "MANYTOONE" + assert rel.uselist is False + rel_kwargs = {} + default_converter._add_relationship_kwargs(rel_kwargs, rel) + assert rel_kwargs["allow_none"] is False + assert rel_kwargs["required"] is True + + rel = models.School.__mapper__.attrs.get("students") + assert rel.direction.name == "ONETOMANY" + assert rel.uselist is True + rel_kwargs = {} + default_converter._add_relationship_kwargs(rel_kwargs, rel) + assert rel_kwargs["allow_none"] is False + assert rel_kwargs["required"] is True + + def test_many_to_many_with_uselist_relationship_kwarg(self, models): + default_converter = ModelConverter() + + rel = models.Student.__mapper__.attrs.get("courses") + assert rel.direction.name == "MANYTOMANY" + assert rel.uselist is True + rel_kwargs = {} + default_converter._add_relationship_kwargs(rel_kwargs, rel) + assert rel_kwargs["allow_none"] is False + assert rel_kwargs["required"] is True + + def test_many_to_many_without_uselist_relationship_kwarg(self, models): + default_converter = ModelConverter() + + rel = models.Lecture.__mapper__.attrs.get("kw") + assert rel.direction.name == "MANYTOMANY" + assert rel.uselist is False + rel_kwargs = {} + default_converter._add_relationship_kwargs(rel_kwargs, rel) + assert rel_kwargs["allow_none"] is True + assert rel_kwargs["required"] is False + + def _repr_validator_list(validators): return sorted(repr(validator) for validator in validators)