0

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.

AtachiShadow
  • 381
  • 4
  • 13

0 Answers0