DB_DataObject manual

本文深入讲解了DB_DataObject的使用方法,包括配置选项、自动构建和数据库模式创建、工厂方法、查询、插入、更新和删除操作,以及如何进行高级筛选、连接和数据选择。同时还介绍了错误处理、类型转换和调试技巧。

DB_DataObject

SQL Builder and Data Modeling Layer

This chapter describes how to use the DB_DataObject SQL Builder and Data Modeling layer

Table of Contents
阅读全文
类别: 编程相关  查看评论

转载于:https://my.oschina.net/yowsah/blog/2151

这是我从数据库中读取存储的这个数据并返回页面相关值的函数,为什么现在读取不到正确的dhcp_option_bind和配置的option redis /tmp/redis/redis_cfg.sock> hgetall "UC_DS_MANUAL_BIND_ENTRY:LAN1|3232235631" 1) "UC_DS_MANUAL_BIND_TBL_IP" 2) "3232235631" 3) "UC_DS_MANUAL_BIND_TBL_CLIENT_ID_STR" 4) "" 5) "poolName" 6) "LAN1" 7) "UC_DS_MANUAL_BIND_TBL_BINDTYPE" 8) "1" 9) "UC_DS_MANUAL_BIND_TBL_MAC" 10) "00-0A-EB-00-13-04" 11) "description" 12) "+++--__" 13) "enable" 14) "1" 15) "optionType60" 16) "2" 17) "optionVal60" 18) "XXX" 19) "optionType150" 20) "3" 21) "optionVal150" 22) "192.168.0.99" static int dhcpServerManualBindOutput(void *data, void *ctx) { APPL_ENSURE_RET(NULL != data && NULL != ctx); int ret = ERR_NO_ERROR; struct in_addr tmpAddr = {}; char ipv4AddStrTmp[IP_ADDRESS_LENGTH] = {0}; char ipv4AddIDStrTmp[IP_ADDRESS_LENGTH] = {0}; char keyStr[IP_ADDRESS_LENGTH + DHCPS_POOLNAME_LEN] = {0}; JSON_Array *pArrArray = (JSON_Array *)ctx; MANUAL_BINDING manualBind = *((MANUAL_BINDING *)data); MANUAL_BINDING manual_bind = {0}; /* 存储一个exclude Ip信息的Json节点 */ JSON_Value *pItemVal = NULL; JSON_Object *pItemObj = NULL; OPTION *getoptionList = NULL; int optNum = 255; int optCount = 0; int bindFlag = 0; char optionLable[16] = {0}; pItemVal = json_value_init_object(); APPL_ENSURE_DONE(ret, NULL != pItemVal, ERR_NO_MEMORY); json_array_append_value(pArrArray, pItemVal); pItemObj = json_value_get_object(pItemVal); APPL_ENSURE_DONE(ret, NULL != pItemObj, ERR_NO_MEMORY); if (0 != strlen(manualBind.vrfName)) { return ERR_NO_ERROR; } getoptionList = pal_calloc(optNum, sizeof(OPTION), "dhcps manual bind options"); if (!getoptionList) { return ERR_NO_MEMORY; } memset(&(tmpAddr), 0, sizeof(struct in_addr)); sprintf(ipv4AddIDStrTmp, "%d", manualBind.ip.s_addr); tmpAddr.s_addr = ntohl(manualBind.ip.s_addr); inet_ntop(AF_INET, &(tmpAddr), ipv4AddStrTmp, sizeof(char) * IP_ADDRESS_LENGTH); ret = uiDhcpServerGetManualBindWithOptionByCid(manualBind.macStr, TRUE, manualBind.poolName, &manual_bind, getoptionList, optNum); for (int i = 0; i < optNum; i++) { if (getoptionList[i].code != 0) { sprintf(optionLable, "option%d", getoptionList[i].code); json_object_set_string(pItemObj, optionLable, getoptionList[i].valStr); optCount++; } } if (tmpAddr.s_addr != 0) { CFG_IMB_INST imb = {0}; sprintf(keyStr, CFG_IMB_INST_TBL_FMT, ipv4AddStrTmp, manualBind.poolName); if (dmCfgIMBInstGet(keyStr, NULL, &imb) == ERR_NO_ERROR) { bindFlag = 1; } else { bindFlag = 0; } } json_object_set_string(pItemObj, "ip", ipv4AddStrTmp); json_object_set_string(pItemObj, "mac", manualBind.macStr); json_object_set_string(pItemObj, "enable", manualBind.enable?"on":"off"); json_object_set_string(pItemObj, "ip_bind", tmpAddr.s_addr == 0?"off":"on"); json_object_set_string(pItemObj, "interface", manualBind.poolName); json_object_set_string(pItemObj, "bind", bindFlag?"1":"0"); json_object_set_string(pItemObj, "note", manualBind.description); json_object_set_string(pItemObj, "id", ipv4AddIDStrTmp); json_object_set_string(pItemObj, "dhcp_option_bind", optCount?"on":"off"); done: pal_free(getoptionList); return ret; } int uiDhcpServerGetManualBindWithOptionByCid(char *cidStr, BOOL isMac, char *poolName, MANUAL_BINDING *manualBind, OPTION optionList[], int optMaxNum) { APPL_ENSURE_RET_VAL(poolName && manualBind && optionList, ERR_BAD_PARAM); int ret = ERROR; TPCONFIG_GET_INFO stGetInfo = {0}; tpConfig_Iter *pIter = NULL; char entryKey[DHCP_SERVER_CONFIGDB_KEY_LEN_MAX] = {}; const char *cidField = NULL;/* mac/cid */ APPL_ENSURE_RET_VAL(poolName && manualBind && optionList && cidStr, ERR_BAD_PARAM); cidField = isMac ? UC_DS_MANUAL_BIND_MAC : UC_DS_MANUAL_BIND_CLIENT_ID_STR; stGetInfo.pGetObj = tpConfig_objCreate(); if (NULL == stGetInfo.pGetObj) { DEBUG_DHCPS("NULL == stGetInfo.pGetObj") return ERR_DHCP_SERVER_GET_TPCONFIG_ERROR; } stGetInfo.type = TPCONFIG_GETTYPE_FUZZY; snprintf(entryKey, sizeof(entryKey), UC_DS_MANUAL_BIND_ENTRY_POOL_ALL, poolName); tpConfig_objAddKey(stGetInfo.pGetObj, entryKey); ret = tpConfig_get(&stGetInfo); if (ret != PFM_ERR_C_OK) { DEBUG_DHCPS("ret %x", ret); ret = ERR_DHCP_SERVER_TPCONFIG_NOT_EXSIT;//ERR_DHCP_SERVER_TPCONFIG_NOT_EXSIT=786475 goto done; } pIter = &stGetInfo.iterName; TPCONFIG_ITER_KEY(pIter) { char *pKey = tpConfig_getKeyName(&stGetInfo.iterName); DEBUG_DHCPS("get_fuzzy key[%s]\r\n", pKey); char *pStr = NULL; BOOL findFlag = FALSE; TPCONFIG_ITER_FV(pIter) { if (PFM_ERR_C_OK == tpConfig_IterGetStrPtr(pIter, &pStr, pKey, cidField)) { DEBUG_DHCPS("get_obj cidStr[%s]\r\n", pStr); findFlag = STR_EQUAL(pStr, cidStr) ? TRUE : FALSE; break; } } /* TODO:优化效率 1.嵌套表 2.有没有办法让迭代器重置到TPCONFIG_ITER_FV这个流程之前? */ if (findFlag) { struct in_addr ip = {}; char tmpPoolName[DHCPS_POOLNAME_LEN] = {}; APPL_IF_ERR_DONE( ret, dhcpPoolAboutKeyNameParse(pKey, UC_DS_MANUAL_BIND_ENTRY_FMT, tmpPoolName, &ip.s_addr)); APPL_IF_ERR_DONE(ret, uiDhcpServerGetManualBindWithOption(ip, poolName, manualBind, optionList, optMaxNum)); } } done: DEBUG_DHCPS("end ret %x", ret); if (stGetInfo.pGetObj) { tpConfig_objFree(stGetInfo.pGetObj); } if (PFM_ERR_C_OK == ret) { ret = ERR_NO_ERROR; } return ret; }
11-26
"import sqlite3 import os import json from datetime import datetime from loguru import logger import pandas as pd class ChatContextManager: """ 聊天上下文管理器 负责存储和检索用户与商品之间的对话历史,使用SQLite数据库进行持久化存储。 支持按会话ID检索对话历史,以及议价次数统计。 """ def __init__(self, max_history=100, db_path="data/chat_history.db"): """ 初始化聊天上下文管理器 Args: max_history: 每个对话保留的最大消息数 db_path: SQLite数据库文件路径 """ self.max_history = max_history self.db_path = db_path self._init_db() def _init_db(self): """初始化数据库表结构""" # 确保数据库目录存在 db_dir = os.path.dirname(self.db_path) if db_dir and not os.path.exists(db_dir): os.makedirs(db_dir) conn = sqlite3.connect(self.db_path) cursor = conn.cursor() # 创建消息表 cursor.execute(''' CREATE TABLE IF NOT EXISTS messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id TEXT NOT NULL, item_id TEXT NOT NULL, role TEXT NOT NULL, content TEXT NOT NULL, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, chat_id TEXT ) ''') # 检查是否需要添加chat_id字段(兼容旧数据库) cursor.execute("PRAGMA table_info(messages)") columns = [column[1] for column in cursor.fetchall()] if 'chat_id' not in columns: cursor.execute('ALTER TABLE messages ADD COLUMN chat_id TEXT') logger.info("已为messages表添加chat_id字段") # 创建索引以加速查询 cursor.execute(''' CREATE INDEX IF NOT EXISTS idx_user_item ON messages (user_id, item_id) ''') cursor.execute(''' CREATE INDEX IF NOT EXISTS idx_chat_id ON messages (chat_id) ''') cursor.execute(''' CREATE INDEX IF NOT EXISTS idx_timestamp ON messages (timestamp) ''') # 创建基于会话ID的议价次数表 cursor.execute(''' CREATE TABLE IF NOT EXISTS chat_bargain_counts ( chat_id TEXT PRIMARY KEY, count INTEGER DEFAULT 0, last_updated DATETIME DEFAULT CURRENT_TIMESTAMP ) ''') # 创建商品信息表 cursor.execute(''' CREATE TABLE IF NOT EXISTS items ( item_id TEXT PRIMARY KEY, data TEXT NOT NULL, price REAL, description TEXT, last_updated DATETIME DEFAULT CURRENT_TIMESTAMP ) ''') # 创建人工标准回答表 cursor.execute(''' CREATE TABLE IF NOT EXISTS manual_answers ( id INTEGER PRIMARY KEY AUTOINCREMENT, question TEXT NOT NULL, answer TEXT NOT NULL, item_id TEXT NOT NULL, chat_id TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE(question, item_id) ) ''') # 创建索引加速查询 cursor.execute(''' CREATE INDEX IF NOT EXISTS idx_manual_answers_question ON manual_answers (question) ''') # 创建索引加速查询 cursor.execute(''' CREATE INDEX IF NOT EXISTS idx_manual_answers_item_id ON manual_answers (item_id) ''') conn.commit() conn.close() logger.info(f"聊天历史数据库初始化完成: {self.db_path}") def save_item_info(self, item_id, item_data): """ 保存商品信息到数据库 Args: item_id: 商品ID item_data: 商品信息字典 """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: # 从商品数据中提取有用信息 price = float(item_data.get('soldPrice', 0)) description = item_data.get('desc', '') # 将整个商品数据转换为JSON字符串 data_json = json.dumps(item_data, ensure_ascii=False) cursor.execute( """ INSERT INTO items (item_id, data, price, description, last_updated) VALUES (?, ?, ?, ?, ?) ON CONFLICT(item_id) DO UPDATE SET data = ?, price = ?, description = ?, last_updated = ? """, ( item_id, data_json, price, description, datetime.now().isoformat(), data_json, price, description, datetime.now().isoformat() ) ) conn.commit() logger.debug(f"商品信息已保存: {item_id}") except Exception as e: logger.error(f"保存商品信息时出错: {e}") conn.rollback() finally: conn.close() def get_item_info(self, item_id): """ 从数据库获取商品信息 Args: item_id: 商品ID Returns: dict: 商品信息字典,如果不存在返回None """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: cursor.execute( "SELECT data FROM items WHERE item_id = ?", (item_id,) ) result = cursor.fetchone() if result: return json.loads(result[0]) return None except Exception as e: logger.error(f"获取商品信息时出错: {e}") return None finally: conn.close() def add_message_by_chat(self, chat_id, user_id, item_id, role, content): """ 基于会话ID添加新消息到对话历史 Args: chat_id: 会话ID user_id: 用户ID (用户消息存真实user_id,助手消息存卖家ID) item_id: 商品ID role: 消息角色 (user/assistant) content: 消息内容 """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: # 插入新消息,使用chat_id作为额外标识 cursor.execute( "INSERT INTO messages (user_id, item_id, role, content, timestamp, chat_id) VALUES (?, ?, ?, ?, ?, ?)", (user_id, item_id, role, content, datetime.now().isoformat(), chat_id) ) # 检查是否需要清理旧消息(基于chat_id) cursor.execute( """ SELECT id FROM messages WHERE chat_id = ? ORDER BY timestamp DESC LIMIT ?, 1 """, (chat_id, self.max_history) ) oldest_to_keep = cursor.fetchone() if oldest_to_keep: cursor.execute( "DELETE FROM messages WHERE chat_id = ? AND id < ?", (chat_id, oldest_to_keep[0]) ) conn.commit() except Exception as e: logger.error(f"添加消息到数据库时出错: {e}") conn.rollback() finally: conn.close() def get_context_by_chat(self, chat_id): """ 基于会话ID获取对话历史 Args: chat_id: 会话ID Returns: list: 包含对话历史的列表 """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: cursor.execute( """ SELECT role, content FROM messages WHERE chat_id = ? ORDER BY timestamp ASC LIMIT ? """, (chat_id, self.max_history) ) messages = [{"role": role, "content": content} for role, content in cursor.fetchall()] # 获取议价次数并添加到上下文中 bargain_count = self.get_bargain_count_by_chat(chat_id) if bargain_count > 0: messages.append({ "role": "system", "content": f"议价次数: {bargain_count}" }) except Exception as e: logger.error(f"获取对话历史时出错: {e}") messages = [] finally: conn.close() return messages def increment_bargain_count_by_chat(self, chat_id): """ 基于会话ID增加议价次数 Args: chat_id: 会话ID """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: # 使用UPSERT语法直接基于chat_id增加议价次数 cursor.execute( """ INSERT INTO chat_bargain_counts (chat_id, count, last_updated) VALUES (?, 1, ?) ON CONFLICT(chat_id) DO UPDATE SET count = count + 1, last_updated = ? """, (chat_id, datetime.now().isoformat(), datetime.now().isoformat()) ) conn.commit() logger.debug(f"会话 {chat_id} 议价次数已增加") except Exception as e: logger.error(f"增加议价次数时出错: {e}") conn.rollback() finally: conn.close() def get_bargain_count_by_chat(self, chat_id): """ 基于会话ID获取议价次数 Args: chat_id: 会话ID Returns: int: 议价次数 """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: cursor.execute( "SELECT count FROM chat_bargain_counts WHERE chat_id = ?", (chat_id,) ) result = cursor.fetchone() return result[0] if result else 0 except Exception as e: logger.error(f"获取议价次数时出错: {e}") return 0 finally: conn.close() def update_manual_answer(self, question, new_answer, item_id, chat_id=None): """ 更新已保存的人工标准回答 Args: question: 原始问题 new_answer: 新的回答内容 item_id: 商品ID chat_id: 会话ID(可选) Returns: bool: 更新是否成功 """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: cursor.execute( "UPDATE manual_answers SET answer = ?, created_at = ? WHERE question = ? AND item_id = ?", (new_answer, datetime.now().isoformat(), question, item_id) ) conn.commit() if cursor.rowcount > 0: logger.info(f"人工标准回答已更新: {question[:30]}...") return True else: logger.warning(f"未找到匹配的人工标准回答: {question[:30]}...") return False except Exception as e: logger.error(f"更新人工标准回答时出错: {e}") conn.rollback() return False finally: conn.close() def save_manual_answer(self, question, answer, item_id, chat_id=None): """ 保存人工标准回答到数据库 Args: question: 用户问题 answer: 人工回答 item_id: 商品ID chat_id: 会话ID(可选) """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: cursor.execute( "INSERT OR IGNORE INTO manual_answers (question, answer, item_id, chat_id, created_at) VALUES (?, ?, ?, ?, ?)", (question, answer, item_id, chat_id, datetime.now().isoformat()) ) conn.commit() logger.info(f"人工标准回答已保存: {question[:30]}...") except Exception as e: logger.error(f"保存人工标准回答时出错: {e}") conn.rollback() finally: conn.close() def get_manual_answer(self, question, item_id): """ 从数据库获取人工标准回答 Args: question: 用户问题 item_id: 商品ID Returns: str: 匹配的人工回答,如果没有找到则返回None """ conn = sqlite3.connect(self.db_path) cursor = conn.cursor() try: # 使用LIKE进行模糊匹配 cursor.execute( "SELECT answer FROM manual_answers WHERE item_id = ? AND question LIKE ? ORDER BY created_at DESC LIMIT 1", (item_id, f"%{question}%") ) result = cursor.fetchone() return result[0] if result else None except Exception as e: logger.error(f"获取人工标准回答时出错: {e}") return None finally: conn.close() "这个是要导入到的目标数据库代码(目标数据库你可以分析这些代码得出),结合之前的信息,我想创建一个新的py文件来将两个excel文件“我已经在根目录文件夹knowledge_base文件夹下创建了'manual_replies.xlsx'文件和'product_summary.xlsx'文件,其中manualreplies.xlsx的表头为"商品ID", "顾客问题"([item_id, user_question, send_message]), "人工回复",product_summary.xlsx中的表头为”商品标题 商品文案 商品链接 价格 “”入此数据库,应该如何实现,不仅告诉我实现的代码,也要告诉我详细操作
08-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值