AutoRpa/rpa_oms/app/inbound/oracle_repo.py

117 lines
3.5 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
# 接口入站无登录用户:创建人/更新人固定 0 / 系统管理员,时间用库时钟。
_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, create_user_id, create_user_name,
update_time, update_user_id, update_user_name,
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, '系统管理员',
SYSDATE, 0, '系统管理员',
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