AutoRpa/rpa_oms/app/inbound/oracle_repo.py

112 lines
3.2 KiB
Python
Raw 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.

"""接口 1 Oracle 落表。
11.2 只能 thick(Instant Client)。Windows 把 Instant Client 目录设到
RPA_ORACLE_CLIENT_LIB。fid 由序列触发器生成,INSERT 不绑这一列。
唯一约束冲突(ORA-00001)当成 oms_id 重复。
"""
from __future__ import annotations
import os
from collections.abc import Callable
from .repo import DuplicateOmsId, RepoUnavailable
_INSERT_SQL = """
INSERT INTO rpa_sales_goods_mapping_data (
oms_id, bar_code, order_date, sale_price, sale_qty, plan_purchase_qty,
goods_id, goods_name, goods_spec, manufacturer, approval_no, unit,
customer_id, customer_name, org_code, goods_mdm_code, customer_mdm_code,
create_time, deal_flag
) VALUES (
:oms_id, :bar_code, :order_date, :sale_price, :sale_qty, :plan_purchase_qty,
:goods_id, :goods_name, :goods_spec, :manufacturer, :approval_no, :unit,
:customer_id, :customer_name, :org_code, :goods_mdm_code, :customer_mdm_code,
SYSDATE, 0
)
"""
_BIND_KEYS = (
"oms_id",
"bar_code",
"order_date",
"sale_price",
"sale_qty",
"plan_purchase_qty",
"goods_id",
"goods_name",
"goods_spec",
"manufacturer",
"approval_no",
"unit",
"customer_id",
"customer_name",
"org_code",
"goods_mdm_code",
"customer_mdm_code",
)
_client_ready = False
class OracleSalesGoodsRepo:
def __init__(self, connect: Callable):
self._connect = connect
@classmethod
def from_env(cls) -> "OracleSalesGoodsRepo":
user = os.getenv("RPA_ORACLE_USER", "")
password = os.getenv("RPA_ORACLE_PASSWORD", "")
host = os.getenv("RPA_ORACLE_HOST", "")
if not user or not password or not host:
raise RepoUnavailable("未配置 RPA_ORACLE_HOST / RPA_ORACLE_USER / RPA_ORACLE_PASSWORD")
port = os.getenv("RPA_ORACLE_PORT", "1521")
service = os.getenv("RPA_ORACLE_SERVICE", "rpa")
dsn = f"{host}:{port}/{service}"
def connect():
_ensure_client()
import oracledb
return oracledb.connect(user=user, password=password, dsn=dsn)
return cls(connect=connect)
def insert(self, record: dict) -> None:
conn = self._connect()
try:
with conn.cursor() as cur:
cur.execute(_INSERT_SQL, {key: record[key] for key in _BIND_KEYS})
conn.commit()
except DuplicateOmsId:
raise
except Exception as exc:
try:
conn.rollback()
except Exception:
pass
if _ora_code(exc) == 1:
raise DuplicateOmsId(record["oms_id"]) from exc
raise RepoUnavailable(str(exc)) from exc
finally:
conn.close()
def _ora_code(exc: BaseException) -> int | None:
if not exc.args:
return None
return getattr(exc.args[0], "code", None)
def _ensure_client() -> None:
# init_oracle_client 每个进程只能调一次。
global _client_ready
if _client_ready:
return
import oracledb
if os.getenv("RPA_ORACLE_THICK", "1") == "1":
lib_dir = os.getenv("RPA_ORACLE_CLIENT_LIB", "")
kwargs = {"lib_dir": lib_dir} if lib_dir else {}
oracledb.init_oracle_client(**kwargs)
_client_ready = True