fix(statements): вставка document_issue пакетами по BATCH (#142, AURORA-1711)
add_issues вставлял все записи документа одним INSERT: 16 параметров на запись, лимит asyncpg 32 767 — потолок около 2 047 замечаний. Лист ОСВ «11.xlsx» (сч. 11, 2 128 строк «Кол. доп.» на парсере контура 40287e1) давал 2 131 предупреждение, маппинг падал с InterfaceError, файл ERROR. Теперь пакеты по BATCH (1000), как у строк и значений форм. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5bec434e1f
commit
01e1f81516
@ -59,7 +59,8 @@ __all__ = [
|
|||||||
"value_flags",
|
"value_flags",
|
||||||
]
|
]
|
||||||
|
|
||||||
# строк на один INSERT: у строки формы 15 колонок, у значения 10; 15 × 1000 < 32767 параметров asyncpg
|
# строк на один INSERT: у строки формы 15 колонок, у значения 10, у `document_issue` 16; 16 × 1000 < 32767 параметров
|
||||||
|
# asyncpg
|
||||||
BATCH = 1000
|
BATCH = 1000
|
||||||
|
|
||||||
|
|
||||||
@ -151,34 +152,30 @@ async def insert_statement(
|
|||||||
async def add_issues(
|
async def add_issues(
|
||||||
session: AsyncSession, document_id: uuid.UUID, drafts: Sequence[IssueDraft], *, now: datetime.datetime
|
session: AsyncSession, document_id: uuid.UUID, drafts: Sequence[IssueDraft], *, now: datetime.datetime
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Записи `document_issue` документа из черновиков (без commit)."""
|
"""Записи `document_issue` документа из черновиков пакетами по `BATCH` (без commit)."""
|
||||||
if not drafts:
|
issues = [
|
||||||
return
|
{
|
||||||
await session.execute(
|
"id": uuid.uuid4(),
|
||||||
insert(DocumentIssue).values(
|
"document_id": document_id,
|
||||||
[
|
"kind": draft.kind,
|
||||||
{
|
"code": draft.code,
|
||||||
"id": uuid.uuid4(),
|
"severity": draft.severity,
|
||||||
"document_id": document_id,
|
"message": draft.message,
|
||||||
"kind": draft.kind,
|
"line_ids": [str(line_id) for line_id in draft.line_ids] or None,
|
||||||
"code": draft.code,
|
"column_id": draft.column_id,
|
||||||
"severity": draft.severity,
|
"column_index": draft.column_index,
|
||||||
"message": draft.message,
|
"codes": list(draft.codes) or None,
|
||||||
"line_ids": [str(line_id) for line_id in draft.line_ids] or None,
|
"field": draft.field,
|
||||||
"column_id": draft.column_id,
|
"source": draft.source,
|
||||||
"column_index": draft.column_index,
|
"relation": draft.relation,
|
||||||
"codes": list(draft.codes) or None,
|
"expected": draft.expected,
|
||||||
"field": draft.field,
|
"actual": draft.actual,
|
||||||
"source": draft.source,
|
"created_at": now,
|
||||||
"relation": draft.relation,
|
}
|
||||||
"expected": draft.expected,
|
for draft in drafts
|
||||||
"actual": draft.actual,
|
]
|
||||||
"created_at": now,
|
for start in range(0, len(issues), BATCH):
|
||||||
}
|
await session.execute(insert(DocumentIssue).values(issues[start : start + BATCH]))
|
||||||
for draft in drafts
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def delete_issues( # noqa: PLR0913 - фильтры записей независимы
|
async def delete_issues( # noqa: PLR0913 - фильтры записей независимы
|
||||||
|
|||||||
@ -527,3 +527,23 @@ async def test_osv_v2_sheet_needs_check_blocks_recognized(seeded: AsyncSession)
|
|||||||
osv["status"] = "needs_check"
|
osv["status"] = "needs_check"
|
||||||
(document,) = await _map(seeded, entity, [osv])
|
(document,) = await _map(seeded, entity, [osv])
|
||||||
assert document.status is DocumentStatus.NEEDS_CHECK
|
assert document.status is DocumentStatus.NEEDS_CHECK
|
||||||
|
|
||||||
|
|
||||||
|
async def test_osv_v2_many_sheet_warnings_stored(seeded: AsyncSession) -> None:
|
||||||
|
"""AURORA-1711: предупреждений листа больше, чем помещается в один INSERT `document_issue` (16 параметров на
|
||||||
|
запись, лимит asyncpg 32 767 — ≈ 2 047 записей). Так было на «11.xlsx» (сч. 11, 2 128 строк «Кол. доп.»):
|
||||||
|
документ создаётся, все предупреждения сохранены."""
|
||||||
|
entity = await _entity(seeded)
|
||||||
|
osv = _osv_doc()
|
||||||
|
count = 2131
|
||||||
|
osv["warnings"] = [
|
||||||
|
{
|
||||||
|
"code": "OSV_ROWS",
|
||||||
|
"severity": "info",
|
||||||
|
"message": f"строка {row}: метка «Кол. доп.» в колонке «Показатели» не распознана",
|
||||||
|
}
|
||||||
|
for row in range(count)
|
||||||
|
]
|
||||||
|
(document,) = await _map(seeded, entity, [osv])
|
||||||
|
assert document.document_type is DocumentType.OSV
|
||||||
|
assert len(await _issues(seeded, document)) == count
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user