I want to perform validation of the config file based on the selected DB. The config file has a key db_type
which can be sqlite
or postgresql
. And depending on the selected database, there should be a sqlite
or postgresql
key, the value of which should be a dictionary with the database connection settings. That is, if db_type = sqlite
, then the postgresql
key may not exist, but the sqlite
key must be. Conversely, if db_type = postgresql
then the sqlite
key may not exist, but the postgresql
key must be. This is how the config looks like:
"db":
{
"db_type": "sqlite",
"sqlite":
{
"filepath": "file_sqlite_db.sqlite",
"create_new": true,
"concurrent_slots": 1
},
"postgresql":
{
"host_db": "0.0.0.0",
"port_db": 5432,
"db_name": "test_db",
"user": "test_user",
"password": "pass",
"concurrent_slots": 100
}
}
What I want to do:
1.
if "db_type" == "sqlite":
pydantic checks the "sqlite" key
pydantic ignore a "postgresql" key
elif "db_type" == "postgresql":
pydantic checks the "postgresql" key
pydantic ignore a "sqlite" key
Separately, this condition can be solved through typing.Optional()
. But what about sqlite
key autocomplete in the following condition:
2.
if not key "sqlite":
fill it with default values
elif the "sqlite" key values are filled incorrectly:
raise ValueError
elif not of the "postgresql" key or the values are filled incorrectly:
raise ValueError
Code examples:
A model built only on BaseModel()
requires both keys (sqlite
and postgresql
). Although I can only describe one sqlite
key in the config and not write postgresql
:
from pydantic import BaseModel, PositiveInt
from enum import Enum
class Config(BaseModel):
class DBConfig(BaseModel):
class DBaseEnum(str, Enum):
sqlite = 'sqlite'
postgresql = 'postgresql'
class SQLITEConfig(BaseModel):
filepath: str = 'file_sqlite_db.sqlite'
create_new: bool = True
concurrent_slots: int = 1
class PSQLConfig(BaseModel):
host_db: str
port_db: int
db_name: str
user: str
password: str
concurrent_slots: PositiveInt
db_type: DBaseEnum = DBaseEnum.sqlite
sqlite: SQLITEConfig
postgresql: PSQLConfig
db: DBConfig
config = {
"db":
{
"db_type": "sqlite",
"sqlite":
{
"filepath": "file_sqlite_db.sqlite",
"create_new": True,
"concurrent_slots": 1
},
"postgresql":
{
"host_db": "0.0.0.0",
"port_db": 5432,
"db_name": "test_db",
"user": "test_user",
"password": "pass",
"concurrent_slots": 100
}
}
}
cfg = Config.parse_obj(config)
print(cfg)
If I delete the postgresql
key in this code, a ValidationError
will be thrown because the model explicitly requires the postgresql
key.