AutoRpa/rpa_oms/app/inbound/oracle_contract_repo.py

110 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 接口 3 Oracle 落表。fid 是订单中心来源序号,INSERT 必须绑这一列。
from __future__ import annotations
from rpa_oracle.errors import RepoUnavailable, is_contract_fid_duplicate
from .oracle_repo import _rollback, in_binds, unique_collisions
_INSERT_SQL = """
INSERT INTO rpa_purchase_contract_data (
fid, oms_id, supplier_id, supplier_name,
contract_sign_date, contract_start_date, contract_end_date,
payment_term, goods_id, goods_name, reg_no, spec, unit,
qty, purchase_tax_rate, unit_price, goods_source_id,
purchaser_id, purchaser_name, planner_id, planner_name,
contract_entry_status, contract_no, org_code, customer_type,
goods_mdm_code, supplier_mdm_code,
process_status, create_time
) VALUES (
:fid, :oms_id, :supplier_id, :supplier_name,
:contract_sign_date, :contract_start_date, :contract_end_date,
:payment_term, :goods_id, :goods_name, :reg_no, :spec, :unit,
:qty, :purchase_tax_rate, :unit_price, :goods_source_id,
:purchaser_id, :purchaser_name, :planner_id, :planner_name,
:contract_entry_status, :contract_no, :org_code, :customer_type,
:goods_mdm_code, :supplier_mdm_code,
0, SYSTIMESTAMP
)
"""
_BIND_KEYS = (
"fid",
"oms_id",
"supplier_id",
"supplier_name",
"contract_sign_date",
"contract_start_date",
"contract_end_date",
"payment_term",
"goods_id",
"goods_name",
"reg_no",
"spec",
"unit",
"qty",
"purchase_tax_rate",
"unit_price",
"goods_source_id",
"purchaser_id",
"purchaser_name",
"planner_id",
"planner_name",
"contract_entry_status",
"contract_no",
"org_code",
"customer_type",
"goods_mdm_code",
"supplier_mdm_code",
)
# 接口 3 连 Oracle 的仓库,管表 3 按 fid 查重和批量插入。
#
# 连接由调用方从池里借来,一个请求一条。
class OraclePurchaseContractRepo:
# 挂上本请求的连接。不要在仓库里再 connect。
def __init__(self, conn):
self._conn = conn
# 查出表 3 里已经有的 fid。空列表不访问库。
def existing_fids(self, fids: list[int]) -> set[int]:
if not fids:
return set()
placeholders, binds = in_binds(fids)
sql = (
"SELECT fid FROM rpa_purchase_contract_data "
f"WHERE fid IN ({placeholders})"
)
try:
with self._conn.cursor() as cur:
cur.execute(sql, binds)
return {row[0] for row in cur.fetchall()}
except Exception as exc:
raise RepoUnavailable("数据库不可用") from exc
# 一次 executemany 插入待写入行。
#
# 返回撞上 pk_rpa_pcd 的 fid。其它唯一约束或库故障抛 RepoUnavailable。
# 成功行在本方法内 commit。
def insert_many(self, records: list[dict]) -> set[int]:
if not records:
return set()
payload = [{key: record[key] for key in _BIND_KEYS} for record in records]
try:
with self._conn.cursor() as cur:
cur.executemany(_INSERT_SQL, payload, batcherrors=True)
collided = unique_collisions(
cur, records, "fid", is_contract_fid_duplicate
)
self._conn.commit()
return collided
except RepoUnavailable:
_rollback(self._conn)
raise
except Exception as exc:
_rollback(self._conn)
if is_contract_fid_duplicate(exc) and len(records) == 1:
return {records[0]["fid"]}
raise RepoUnavailable("数据库不可用") from exc