Search code examples
pythonfastapipydantic

How to use a reserved keyword in pydantic model


I need to create a schema but it has a column called global, and when I try to write this, I got an error.

class User(BaseModel):

    id:int
    global:bool

I try to use another name, but gives another error when try to save in db.


Solution

  • It looks like you are using a pydantic module. You can't use the name global because it's a reserved keyword so you need to use this trick to convert it.

    pydantic v1:

    class User(BaseModel):
        id: int
        global_: bool
    
        class Config:
            fields = {
                'global_': 'global'
            }
    

    or pydantic v1 & v2:

    class User(BaseModel):
        id: int
        global_: bool = Field(..., alias='global')
    

    To create a class you have to use a dictionary (because User(id=1, global=False) also throws an error):

    user = User(id=1, global=False)
    
    > Traceback (most recent call last):
    > (...)
    > File "<input>", line 1
    >  User(id=1, global=False)
    >             ^^^^^^
    > SyntaxError: invalid syntax
    
    user = User(**{'id': 1, 'global': False})
    

    Set allow_population_by_field_name = True or populate_by_name=True in config to allow creating models using both global and global_ names (thanks @GooDeeJAY).

    pydantic v1:

    class User(BaseModel):
        id: int
        global_: bool = Field(..., alias='global')
    
        class Config:
            allow_population_by_field_name = True
    

    pydantic v2:

    class User(BaseModel):
        id: int
        global_: bool = Field(..., alias='global')
        model_config = ConfigDict(populate_by_name=True)
    
    
    user1 = User(**{'id': 1, 'global': False})
    user2 = User(id=1, global_=False)
    assert user1 == user2
    

    By default schema dump will not use aliased fields:

    user.dict() # for pydantic v1
    user.model_dump() # for pydantic v2
    > {'id': 1, 'global_': False}
    

    To get data in the correct schema use by_alias:

    user.dict(by_alias=True) # for pydantic v1
    user.model_dump(by_alias=True) # for pydantic v2
    > {'id': 1, 'global': False}