В конечном итоге модели используются для преобразования Polars dataframes в данные json для использования Tabulator — библиотекой форматирования таблиц HTML/JS, поэтому порядок определенно имеет значение, и модели — хорошее место для хранения этой информации. Я даже встроил директивы форматирования для Tabulator с помощью Annotated.
Поэтому я хочу определить более мелкие подмодели с тем, что специфично для каждой модели, а также определение повторяющихся групп полей. Затем соберите их с помощью множественного наследования.
На их форумах был вопрос, посвященный построению моделей с помощью множественного наследования, и хотя отвечавший не решался одобрить этот подход, он все же сказал, что при условии, что функциональность была стабильной частью поведения Pydantic.
А как насчет упорядочения полей, которое, похоже, происходит в обратном порядке заказать?
Примеры данных:
Project shape: (2, 7)┌─────────┬───────┬──────────┬──────────┬───────────┬─────────────┬─────────────┐
│ project ┆ descr ┆ present0 ┆ present1 ┆ usercount ┆ lastupdater ┆ lastupddttm │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ i64 ┆ i64 ┆ i64 ┆ str ┆ str │
╞═════════╪═══════╪══════════╪══════════╪═══════════╪═════════════╪═════════════╡
│ project ┆ d ┆ 0 ┆ 1 ┆ 77 ┆ mcuban ┆ 2009 │
│ project ┆ d ┆ 0 ┆ 1 ┆ 77 ┆ mcuban ┆ 2009 │
└─────────┴───────┴──────────┴──────────┴───────────┴─────────────┴─────────────┘
Customer shape: (2, 7)
┌──────────┬───────┬──────────┬──────────┬───────────┬─────────────┬─────────────┐
│ customer ┆ descr ┆ present0 ┆ present1 ┆ usercount ┆ lastupdater ┆ lastupddttm │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ str ┆ str ┆ i64 ┆ i64 ┆ i64 ┆ str ┆ str │
╞══════════╪═══════╪══════════╪══════════╪═══════════╪═════════════╪═════════════╡
│ proj ┆ d ┆ 0 ┆ 1 ┆ 77 ┆ jsmith ┆ 1999 │
│ proj ┆ d ┆ 0 ┆ 1 ┆ 77 ┆ jsmith ┆ 1999 │
└──────────┴───────┴──────────┴──────────┴───────────┴─────────────┴─────────────┘
Тестовый код — T2project_rev_order_columns дает правильный порядок
import sysfrom rich import inspect as rin
import pydantic as pyd
import polars as pl
verbose = "-v" in sys.argv
class Project(pyd.BaseModel):
"""my reference field order"""
project : str = "project"
descr : str = "d"
present0 : int = 0
present1 : int = 1
usercount : int = 77
lastupdater : str = "mcuban"
lastupddttm : str = "2009"
class Customer(pyd.BaseModel):
customer : str = "proj"
descr : str = "d"
present0 : int = 0
present1 : int = 1
usercount : int = 77
lastupdater : str = "jsmith"
lastupddttm : str = "1999"
# assemble by components
class KProject(pyd.BaseModel):
project : str = "project"
descr : str = "d"
class Pres(pyd.BaseModel):
present0 : int = 0
present1 : int = 1
class Tag(pyd.BaseModel):
usercount : int = 77
class Upd(pyd.BaseModel):
lastupdater : str = "jsmith"
lastupddttm : str = "1999"
class T1project_order_columns(KProject, Pres, Tag, Upd):
pass
class T2project_rev_order_columns(Upd, Tag, Pres, KProject):
"""ordering works, but is that guaranteed by Pydantic?"""
def test():
def build_df(cls_):
df = pl.from_dicts([cls_().model_dump() for i in range(0,2)])
if verbose:
print("\n\n", cls_.__name__, df)
return df.columns
dataexp = [
Project,
Customer,
T1project_order_columns,
T2project_rev_order_columns,
]
for cls_ in dataexp:
got = build_df(cls_)
if cls_ is Project:
exp = got
classname = f"{cls_.__name__:30.30}"
if not classname.startswith("T"):
continue
if exp == got:
print(f"
else:
msg2 = f"
print(f"{msg2} exp:{','.join(exp)}\n{' ' * (len(msg2)+2)}got:{','.join(got)}\n")
test()
выход:
got:lastupdater,lastupddttm,usercount,present0,present1,project,descr
Вопрос: это гарантия заказа или деталь реализации?
p.s. только для информации — встраивание дополнительных директив метаданных в модель
Вы не можете использовать модели pydantic в Annotated, это приведет к какой-то странной ошибке pydantic. Неpydantic типы данных, такие как классы данных, работают. Annotated — это кортеж, вам придется просмотреть его составляющие и направить конфигурацию к интересующим компонентам.@dataclass
class TabulatorSettings:
"use on Tab Models as Annotated dont use a pydantic model in Annotated metadata"
urlField: str = ""
title: str = ""
formatter: str = ""
class CompareGeneral_TabData(pyd.BaseModel):
label: str
value: Annotated[Any, TabulatorSettings(title="Left", formatter="html", width=100)]
value_oth: Annotated[Any, TabulatorSettings(title="Right", formatter="html", width=100)]
Подробнее здесь: https://stackoverflow.com/questions/793 ... table-feat