From 22f370322412074174cde20ecfd14ec03657ab63 Mon Sep 17 00:00:00 2001
From: lyg <1543117173@qq.com>
Date: 星期一, 07 七月 2025 16:20:25 +0800
Subject: [PATCH] 生成数据库

---
 knowledgebase/db/db_helper.py |  283 ++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 170 insertions(+), 113 deletions(-)

diff --git a/knowledgebase/db/db_helper.py b/knowledgebase/db/db_helper.py
index 4f193d1..0a14bdc 100644
--- a/knowledgebase/db/db_helper.py
+++ b/knowledgebase/db/db_helper.py
@@ -1,21 +1,40 @@
 import uuid
 from enum import Enum
+from threading import RLock
 
 from sqlalchemy.orm import sessionmaker, scoped_session
 
-from knowledgebase.db.models import engine, TProject, TDevice, TDataStream, TDevStream, TRule, TRuleEnc, TPropertyEnc, \
+from knowledgebase.db.models import get_engine, TProject, TDevice, TDataStream, TDevStream, TRule, TRuleEnc, TPropertyEnc, \
     TPropertyLinear, TRuleStream, TEncLinear, TRuleLinear, TParameter, TParameterType, TExtendInfo, TRulekeyInfo, \
     TInsFormat
 
 from hashlib import md5
 
-# 鍒涘缓涓�涓細璇濆伐鍘�
-session_factory = sessionmaker(bind=engine)
-# 鍒涘缓涓�涓細璇濆璞�
-Session = scoped_session(session_factory)
-session = Session()
+_session = None
 
 _para_id_map = {}
+
+db_lock = RLock()
+
+def get_session():
+    global _session
+    return _session
+
+def init_db_helper():
+    # 鍒涘缓涓�涓細璇濆伐鍘�
+    session_factory = sessionmaker(bind=get_engine())
+    # 鍒涘缓涓�涓細璇濆璞�
+    Session = scoped_session(session_factory)
+    global _session
+    _session = Session()
+
+def th_safe(func):
+    def wrapper(*args, **kwargs):
+        with db_lock:
+            result = func(*args, **kwargs)
+        return result
+
+    return wrapper
 
 
 def get_pk():
@@ -24,12 +43,13 @@
     return pk
 
 
+@th_safe
 def create_project(sat_id, sat_name, proj_code, proj_name, desc, date_time, ) -> TProject:
     """
     鍒涘缓project
     :param sat_id:
-    :param sat_name: 
-    :param proj_code: 
+    :param sat_name:
+    :param proj_code:
     :param proj_name:
     :param desc:
     :param date_time:
@@ -39,11 +59,12 @@
                        C_DESCRIPTION=desc, C_HASH=uuid.uuid4().int & 0xffffffff, C_PROJECT_NAME=proj_name,
                        C_DATETIME=date_time,
                        C_CREATEOR='')
-    session.add(project)
-    session.commit()
+    _session.add(project)
+    _session.commit()
     return project
 
 
+@th_safe
 def create_device(device_id, device_name, device_type, dll, project_pk):
     """
     鍒涘缓device
@@ -56,11 +77,12 @@
     """
     device = TDevice(C_DEV_PK=get_pk(), C_DEV_ID=device_id, C_DEV_NAME=device_name, C_DEV_TYPE=device_type, C_DLL=dll,
                      C_PROJECT_PK=project_pk)
-    session.add(device)
-    session.commit()
+    _session.add(device)
+    _session.commit()
     return device
 
 
+@th_safe
 def create_extend_info(proj_pk, prop_id, prop_name, val, fk):
     ext_info = TExtendInfo(
         C_PK=get_pk(),
@@ -70,10 +92,11 @@
         C_VAL=val,
         C_FOREIGN_PK=fk
     )
-    session.add(ext_info)
-    session.commit()
+    _session.add(ext_info)
+    _session.commit()
 
 
+@th_safe
 def create_data_stream(proj_pk, dev_pk, name, code, data_ty, direct, rule_id, rule_ty, rule_pk=None):
     """
     鍒涘缓data_stream
@@ -96,33 +119,38 @@
                      C_DESCRIPTION='',
                      C_RULE_ID=rule_id,
                      C_RULE_TYPE=rule_ty)
-    session.add(ds)
+    _session.add(ds)
     link = TDevStream(C_PK=get_pk(), C_DEV_PK=dev_pk, C_STREAM_PK=ds.C_STREAM_PK, C_PROJECT_PK=proj_pk)
-    session.add(link)
+    _session.add(link)
     rule_enc = None
     # 鍒涘缓瑙f瀽瑙勫垯
     if rule_pk is None:
         rule_pk = get_pk()
         if rule_ty == '001':
             # 灏佽鍖�
-            rule_enc = create_rule_enc(proj_pk, rule_pk, rule_id, rule_id)
+            rule_enc = _create_rule_enc(proj_pk, rule_pk, rule_id, rule_id)
 
-    rule = create_rule(proj_pk, ds.C_STREAM_PK, rule_id, name, None, None, '0')
-    rule = create_rule(proj_pk, rule_pk, rule_id, rule_id, None, ds.C_STREAM_PK, '1')
+    rule = _create_rule(proj_pk, ds.C_STREAM_PK, rule_id, name, None, None, '0')
+    rule = _create_rule(proj_pk, rule_pk, rule_id, rule_id, None, ds.C_STREAM_PK, '1')
     # rule stream
-    rule_stream = create_rule_stream(proj_pk,
-                                     rule_pk,
-                                     ds.C_STREAM_PK,
-                                     ds.C_STREAM_ID,
-                                     ds.C_NAME,
-                                     ds.C_STREAM_DIR,
-                                     f"{ds.C_NAME}/{rule_id}/")
-    session.add(rule_stream)
-    session.commit()
+    rule_stream = _create_rule_stream(proj_pk,
+                                      rule_pk,
+                                      ds.C_STREAM_PK,
+                                      ds.C_STREAM_ID,
+                                      ds.C_NAME,
+                                      ds.C_STREAM_DIR,
+                                      f"{ds.C_NAME}/{rule_id}/")
+    _session.add(rule_stream)
+    _session.commit()
     return ds, rule_stream, rule_enc
 
 
+@th_safe
 def create_rule(proj_pk, rule_pk, rule_id, rule_name, rule_len, parent_pk, flag, actual_parent_pk=None):
+    return _create_rule(proj_pk, rule_pk, rule_id, rule_name, rule_len, parent_pk, flag, actual_parent_pk)
+
+
+def _create_rule(proj_pk, rule_pk, rule_id, rule_name, rule_len, parent_pk, flag, actual_parent_pk=None):
     rule = TRule(
         C_PK=get_pk(),
         C_PROJECT_PK=proj_pk,
@@ -134,16 +162,22 @@
         C_FLAG=flag,
         C_ACTUAL_PARENT_PK=actual_parent_pk
     )
-    session.add(rule)
-    session.commit()
+    _session.add(rule)
+    _session.commit()
     return rule
 
 
+@th_safe
 def find_rule_by_rule_id(rule_id):
-    return session.query(TRule).filter(TRule.C_RULE_ID == rule_id).first()
+    return _session.query(TRule).filter(TRule.C_RULE_ID == rule_id).first()
 
 
+@th_safe
 def create_rule_stream(proj_pk, rule_pk, stream_pk, stream_id, stream_name, stream_dir, _path):
+    return _create_rule_stream(proj_pk, rule_pk, stream_pk, stream_id, stream_name, stream_dir, _path)
+
+
+def _create_rule_stream(proj_pk, rule_pk, stream_pk, stream_id, stream_name, stream_dir, _path):
     rule_stream = TRuleStream(
         C_PK=get_pk(),
         C_PROJECT_PK=proj_pk,
@@ -154,22 +188,28 @@
         C_STREAM_DIR=stream_dir,
         C_PATH=_path
     )
-    session.add(rule_stream)
-    session.commit()
+    _session.add(rule_stream)
+    _session.commit()
     return rule_stream
 
 
+@th_safe
 def create_ref_ds_rule_stream(proj_pk, stream_pk, stream_id, stream_name, stream_dir, target_stream_pk):
-    items: list = session.query(TRuleStream).filter(TRuleStream.C_STREAM_PK == target_stream_pk).all()
+    items: list = _session.query(TRuleStream).filter(TRuleStream.C_STREAM_PK == target_stream_pk).all()
     for it in items:
         _path = it.C_PATH
         if len(_path.split('/')) == 3:
             continue
         _path = f'{stream_name}/{stream_id}/'.join(_path.split('/')[2:]) + '/'
-        create_rule_stream(proj_pk, it.C_RULE_PK, stream_pk, stream_id, stream_name, stream_dir, _path)
+        _create_rule_stream(proj_pk, it.C_RULE_PK, stream_pk, stream_id, stream_name, stream_dir, _path)
 
 
+@th_safe
 def create_rule_enc(proj_pk, enc_pk, enc_id, name, content=None):
+    return _create_rule_enc(proj_pk, enc_pk, enc_id, name, content)
+
+
+def _create_rule_enc(proj_pk, enc_pk, enc_id, name, content=None):
     rule_enc = TRuleEnc(
         C_ENC_PK=enc_pk,
         C_PROJECT_PK=proj_pk,
@@ -177,11 +217,12 @@
         C_NAME=name,
         C_CONTENT=content,
     )
-    session.add(rule_enc)
-    session.commit()
+    _session.add(rule_enc)
+    _session.commit()
     return rule_enc
 
 
+@th_safe
 def create_rule_linear(proj_pk, linear_pk, linear_id, name, length, content):
     rule_linear = TRuleLinear(
         C_LINEAR_PK=linear_pk,
@@ -193,11 +234,12 @@
         C_REL_LINEAR_PK=None,
         C_CONTENT=content
     )
-    session.add(rule_linear)
-    session.commit()
+    _session.add(rule_linear)
+    _session.commit()
     return rule_linear
 
 
+@th_safe
 def create_property_enc(proj_pk, enc_pk, segment_id, name, ty, content, offset,
                         length, msb_first, mask, cond, seq, rel_enc_item_pk, para_id):
     property_enc = TPropertyEnc(
@@ -218,7 +260,7 @@
         C_REL_ENCITEM_PK=rel_enc_item_pk,
         C_PAR_ID=para_id
     )
-    session.add(property_enc)
+    _session.add(property_enc)
     para = TParameter(
         C_PAR_PK=get_pk(),
         C_PROJECT_PK=proj_pk,
@@ -235,7 +277,7 @@
         C_REG_PK=None,
         C_METHOD_PK=None
     )
-    session.add(para)
+    _session.add(para)
     if ty == 'ENUM' and content:
         items: list = content.split(' ')
         for item in items:
@@ -250,8 +292,8 @@
                 C_PAR_PK=para.C_PAR_PK,
                 C_PROJECT_PK=proj_pk
             )
-            session.add(pt)
-    session.commit()
+            _session.add(pt)
+    _session.commit()
     return property_enc
 
 
@@ -264,8 +306,16 @@
             return _para_id
 
 
+para_id_pk_map = {}
+
+
+@th_safe
 def create_property_linear(proj_pk, linear_pk, para_id, name, ty, content, offset,
                            length, msb_first, mask, cond, calc_expr, simuval, reg_par, params, seq):
+
+    par_pk = get_pk()
+    if para_id in para_id_pk_map:
+        par_pk = para_id_pk_map[para_id]
     property_linear = TPropertyLinear(
         C_PK=get_pk(),
         C_LINEAR_PK=linear_pk,
@@ -278,7 +328,7 @@
         C_MASK=mask,
         C_CONDITION=cond,
         C_CALC_EXPR=calc_expr,
-        C_PAR_PK=get_pk(),
+        C_PAR_PK=par_pk,
         C_SIMUVAL=simuval,
         C_REG_PAR=reg_par,
         C_PARAMS=params,
@@ -286,45 +336,47 @@
         C_SEQ=seq,
         C_REL_PK=None
     )
-    session.add(property_linear)
-    if para_id in _para_id_map:
-        get_para_id(para_id)
-    para = TParameter(
-        C_PAR_PK=property_linear.C_PAR_PK,
-        C_PROJECT_PK=proj_pk,
-        C_PAR_CODE=para_id,
-        C_PAR_NAME=name,
-        C_SUBSYS=None,
-        C_TYPE=None,
-        C_UNIT=None,
-        C_VALUE_RANGE=None,
-        C_DIS_REQUIRE=None,
-        C_MODULUS=None,
-        C_PARAMS=None,
-        C_PRECISION='0',
-        C_REG_PK=None,
-        C_METHOD_PK=None
-    )
-    session.add(para)
-    if ty == 'ENUM' and content:
-        items: list = content.split(' ')
-        for item in items:
-            idx = items.index(item)
-            name, val = item.split(',')
-            pt = TParameterType(
-                C_PK=get_pk(),
-                C_TYPE_ID=f'{idx}',
-                C_TYPE_NAME=name,
-                C_VALUE=val,
-                C_DATA_TYPE=None,
-                C_PAR_PK=para.C_PAR_PK,
-                C_PROJECT_PK=proj_pk
-            )
-            session.add(pt)
-    session.commit()
+    _session.add(property_linear)
+    if para_id not in para_id_pk_map:
+        if para_id in _para_id_map:
+            get_para_id(para_id)
+        para = TParameter(
+            C_PAR_PK=property_linear.C_PAR_PK,
+            C_PROJECT_PK=proj_pk,
+            C_PAR_CODE=para_id,
+            C_PAR_NAME=name,
+            C_SUBSYS=None,
+            C_TYPE=None,
+            C_UNIT=None,
+            C_VALUE_RANGE=None,
+            C_DIS_REQUIRE=None,
+            C_MODULUS=None,
+            C_PARAMS=None,
+            C_PRECISION='0',
+            C_REG_PK=None,
+            C_METHOD_PK=None
+        )
+        _session.add(para)
+        if ty == 'ENUM' and content:
+            items: list = content.split(' ')
+            for item in items:
+                idx = items.index(item)
+                name, val = item.split(',')
+                pt = TParameterType(
+                    C_PK=get_pk(),
+                    C_TYPE_ID=f'{idx}',
+                    C_TYPE_NAME=name,
+                    C_VALUE=val,
+                    C_DATA_TYPE=None,
+                    C_PAR_PK=para.C_PAR_PK,
+                    C_PROJECT_PK=proj_pk
+                )
+                _session.add(pt)
+    _session.commit()
     return property_linear
 
 
+@th_safe
 def create_enc_linear(proj_pk, enc_item_pk, ty, vals=None, linear_pk=None):
     """
     鍒涘缓 t_enc_linear
@@ -345,19 +397,21 @@
         C_TYPE=ty,
         C_FOLDER_PK=None
     )
-    session.add(enc_linear)
-    session.commit()
+    _session.add(enc_linear)
+    _session.commit()
     return enc_linear
 
 
+@th_safe
 def update_rule_enc(rule_enc):
     # 鏇存柊
-    session.query(TRuleEnc).filter(TRuleEnc.C_ENC_PK == rule_enc.C_ENC_PK).update({
+    _session.query(TRuleEnc).filter(TRuleEnc.C_ENC_PK == rule_enc.C_ENC_PK).update({
         TRuleEnc.C_KEY: rule_enc.C_KEY
     })
-    session.commit()
+    _session.commit()
 
 
+@th_safe
 def create_rulekey_info(proj_pk, rule_pk, rule_id, rule_name, key_pk, key_id, key_name, key_val):
     info = TRulekeyInfo(
         C_PK=get_pk(),
@@ -370,8 +424,8 @@
         C_KEY_NAME=key_name,
         C_KEY_VAL=key_val
     )
-    session.add(info)
-    session.commit()
+    _session.add(info)
+    _session.commit()
 
 
 ins_ty = {
@@ -392,43 +446,43 @@
 
 
 class BinaryType(Enum):
-    Integer = 0 # 鏁村瀷
-    Float = 1 # 娴偣鍨�
-    Ascii = 2 # ASCII
+    Integer = 0  # 鏁村瀷
+    Float = 1  # 娴偣鍨�
+    Ascii = 2  # ASCII
 
 
 class NumberDataType(Enum):
-    Unsigned = 0 # 鏃犵鍙锋暣鍨�
-    SignInteger = 1 # 鏈夌鍙锋暣鍨�
-    Phy = 2 # 鐗╃悊閲�
-    Bytes = 3 # 澶氬瓧鑺傜爜
+    Unsigned = 0  # 鏃犵鍙锋暣鍨�
+    SignInteger = 1  # 鏈夌鍙锋暣鍨�
+    Phy = 2  # 鐗╃悊閲�
+    Bytes = 3  # 澶氬瓧鑺傜爜
 
 
 class InputFormat(Enum):
-    Binary = 0 # 浜岃繘鍒�
-    Decimal = 1 # 鍗佽繘鍒�
-    Hex = 2 # 鍗佸叚杩涘埗
+    Binary = 0  # 浜岃繘鍒�
+    Decimal = 1  # 鍗佽繘鍒�
+    Hex = 2  # 鍗佸叚杩涘埗
 
 
 class ProcessMethod(Enum):
-    Dirct = 0 # 鐩磋
-    Equivalent = 1 # 褰撻噺
-    Formula = 2 # 鍏紡
-    Script = 3 # 鑴氭湰
+    Dirct = 0  # 鐩磋
+    Equivalent = 1  # 褰撻噺
+    Formula = 2  # 鍏紡
+    Script = 3  # 鑴氭湰
 
 
 class ExpressionType(Enum):
-    Count = 0 # 涓暟璁$畻
-    Formula = 1 # 鏁板�艰绠�
+    Count = 0  # 涓暟璁$畻
+    Formula = 1  # 鏁板�艰绠�
 
 
 class EnumType(Enum):
-    NameValue = 0 # 鍚嶅�煎鏋氫妇
-    Range = 1 # 鑼冨洿鏋氫妇
-    Classify = 2 # 澶氱骇鍒嗙被
-    InsCategory = 3 # 鎸囦护绫诲埆鏋氫妇
-    InsUnit = 4 # 鎸囦护鍗曞厓鏋氫妇
-    InsFormat = 5 # 鎸囦护鏍煎紡鏋氫妇
+    NameValue = 0  # 鍚嶅�煎鏋氫妇
+    Range = 1  # 鑼冨洿鏋氫妇
+    Classify = 2  # 澶氱骇鍒嗙被
+    InsCategory = 3  # 鎸囦护绫诲埆鏋氫妇
+    InsUnit = 4  # 鎸囦护鍗曞厓鏋氫妇
+    InsFormat = 5  # 鎸囦护鏍煎紡鏋氫妇
 
 
 def make_attr(field: dict):
@@ -451,16 +505,19 @@
     attr = 0
     # 鍗虫椂杈撳叆锛屾棤绗﹀彿鏁存暟锛屽崄杩涘埗锛岀洿璇�
     if field['type'] == ins_ty['input']:
-        attr |= (NumberDataType.Unsigned.value << 3) | (InputFormat.Decimal.value << 6) | (ProcessMethod.Dirct.value << 11)
+        attr |= (NumberDataType.Unsigned.value << 3) | (InputFormat.Decimal.value << 6) | (
+                ProcessMethod.Dirct.value << 11)
     # 鏄惁鏄瓙鍖�
-    attr |= (1 << 9) if field['type']==ins_ty['subPkt'] else 0
+    attr |= (1 << 9) if field['type'] == ins_ty['subPkt'] else 0
     # 鏄惁鏄彂閫佹爣璁�
-    attr |= (1 << 10) if field['type']==ins_ty['sendFlag'] else 0
+    attr |= (1 << 10) if field['type'] == ins_ty['sendFlag'] else 0
     # 璁$畻绫诲瀷
     # 鏋氫妇绫诲瀷
 
     return attr
 
+
+@th_safe
 def create_ins_format(proj_pk: str, parent_pk: str, info: dict) -> TInsFormat:
     ins_format = TInsFormat(
         C_INS_FORMAT_PK=get_pk(),
@@ -480,6 +537,6 @@
         C_FORMULA=info['formula'] if 'formula' in info else '',
         C_NUMBER='',
     )
-    session.add(ins_format)
-    session.commit()
+    _session.add(ins_format)
+    _session.commit()
     return ins_format

--
Gitblit v1.9.1