question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Required Optional fields

See original GitHub issue

Question

Currently, adding an Optional field just removes the field from the generated required fields list in the schema/JSON schema. Is there a mechanism for having it instead generate an anyOf field requirement and requiring a field with a null value?

Please complete:

  • OS: Mac OS X
  • Python version import sys; print(sys.version): 3.7.4 (default, Oct 12 2019, 18:55:28)
  • Pydantic version import pydantic; print(pydantic.VERSION): 1.1

I couldn’t find info on this in the help manual, though the general documentation for Union (link) doesn’t specifically call out that it behaves differently with None.

from typing import Optional
import pydantic

class Metadata(pydantic.BaseModel):
    nullable_field = Optional[str]

Would love a way to generate {"anyOf": [{"type": "string"}, {"type": null}]}, though I realize that passing {} and {"nullable_field": None} will generate equivalent Pydantic models.

Thanks for the help and the library!

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:5
  • Comments:15 (9 by maintainers)

github_iconTop GitHub Comments

13reactions
yurikhancommented, Jun 18, 2020

I’m the kind of guy who is known to rant about optionals, nulls, zeros, empty strings, empty arrays and empty objects and how all of them are distinct cases. Would really like if all of the cases here and in various linked issues could be easily expressed in a Pydantic model and mapped to JSON Schema equivalents. I’ll try to summarize the current ways and workarounds to do it:

  • A field is required and cannot be null. — Works out of the box
    class Foo(BaseModel):
        foo: int
    
    Foo()
    # ValidationError: field required
    Foo(foo=42)
    # Foo(foo=42)
    Foo(foo=None)
    # ValidationError: none is not an allowed value
    Foo.schema()
    # {'properties': {'foo': {'title': 'Foo', 'type': 'integer'}},
    #  'required': ['foo'],
    #  'title': 'Foo',
    #  'type': 'object'}
    
  • A field is required and can be null. — Requires a schema patch
    class Foo(BaseModel):
        foo: Optional[int] = ...
    
        class Config:
            def schema_extra(schema, model):
                schema['properties']['foo'].update({'type': ['null', 'integer']})
    
    Foo()
    # ValidationError: field required
    Foo(foo=42)
    # Foo(foo=42)
    Foo(foo=None)
    # Foo(foo=None)
    Foo.schema()
    # {'properties': {'foo': {'title': 'Foo', 'type': ['null', 'integer']}},
    #  'required': ['foo'],
    #  'title': 'Foo',
    #  'type': 'object'}
    
  • A field is optional but if present cannot be null. — Requires a validator
    class Foo(BaseModel):
        foo: Optional[int]
    
        @validator('foo')
        def not_null(cls, v):
            if v is None:
                raise ValueError
            return v
    
    Foo()
    # Foo(foo=None)
    Foo(foo=42)
    # Foo(foo=42)
    Foo(foo=None)
    # ValidationError: type_error
    Foo.schema()
    # {'properties': {'foo': {'title': 'Foo', 'type': 'integer'}},
    #  'title': 'Foo',
    #  'type': 'object'}
    
  • A field is optional and may be null. — Requires a schema patch
    class Foo(BaseModel):
        foo: Optional[int]
    
        class Config:
            def schema_extra(schema, model):
                schema['properties']['foo'].update({'type': ['null', 'integer']})
    
    Foo()
    # Foo(foo=None)
    Foo(foo=42)
    # Foo(foo=42)
    Foo(foo=None)
    # Foo(foo=None)
    Foo.schema()
    # {'properties': {'foo': {'title': 'Foo', 'type': ['null', 'integer']}},
    #  'title': 'Foo',
    #  'type': 'object'}
    

Is that right, are those the easiest workarounds, and does the above cover all interesting cases?

(Cue OpenAPI users bickering that arrays in type will only be supported in 3.1+ while 3.0 uses a private extension "nullable": true.)

3reactions
spacethercommented, Jun 3, 2022

How about changing the issue name to required nullable fields

Read more comments on GitHub >

github_iconTop Results From Across the Web

Marking Required Fields in Forms - Nielsen Norman Group
Using an asterisk to mark required fields is an easy way to improve the usability of your forms. Only marking optional fields makes...
Read more >
Form fields — Required vs Optional | by jordane sanson
There are always more fields required than optional. Less visual noise on your form makes it more readable and therefore faster to complete....
Read more >
How to indicate required and optional fields in forms
Another common approach seen in forms is to mark the mandatory fields with an asterisk and not mark the optional fields.
Read more >
What is the difference between Required, Conditionally ...
Optional fields are not required to save the credit as complete and have no impact on scoring. They are included to give participants...
Read more >
Why Users Opt Out Forms That Mark Required Fields
You can make your form less intimidating on the first impression by marking optional fields instead of required fields.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found