ai客服
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
5.3 KiB

1 month ago
  1. import yaml
  2. import pymysql
  3. import os
  4. from datetime import datetime
  5. class DBManager:
  6. def __init__(self, config_path="config.yaml"):
  7. self.config_path = config_path
  8. self.conn = None
  9. self._load_config()
  10. self._ensure_table_exists()
  11. def _load_config(self):
  12. try:
  13. with open(self.config_path, 'r', encoding='utf-8') as f:
  14. config = yaml.safe_load(f)
  15. mysql_cfg = config.get('mysql', {})
  16. # 处理 host:port 字符串
  17. host_port = mysql_cfg.get('host', '127.0.0.1:3306')
  18. if ':' in host_port:
  19. self.host, self.port = host_port.split(':')
  20. self.port = int(self.port)
  21. else:
  22. self.host = host_port
  23. self.port = 3306
  24. self.user = mysql_cfg.get('username')
  25. self.password = mysql_cfg.get('password')
  26. self.database = mysql_cfg.get('dbname')
  27. except Exception as e:
  28. print(f"[DBManager] 加载配置失败: {e}")
  29. raise
  30. def get_connection(self):
  31. try:
  32. if self.conn is None or not self.conn.open:
  33. self.conn = pymysql.connect(
  34. host=self.host,
  35. port=self.port,
  36. user=self.user,
  37. password=self.password,
  38. database=self.database,
  39. charset='utf8mb4',
  40. cursorclass=pymysql.cursors.DictCursor,
  41. autocommit=True
  42. )
  43. return self.conn
  44. except Exception as e:
  45. print(f"[DBManager] 数据库连接失败: {e}")
  46. return None
  47. def _ensure_table_exists(self):
  48. conn = self.get_connection()
  49. if not conn:
  50. return
  51. try:
  52. with conn.cursor() as cursor:
  53. create_table_sql = """
  54. CREATE TABLE IF NOT EXISTS douyin_products (
  55. id INT AUTO_INCREMENT PRIMARY KEY,
  56. name VARCHAR(512) NOT NULL,
  57. img_url TEXT,
  58. stock INT DEFAULT 0,
  59. status VARCHAR(64),
  60. delivery_time VARCHAR(256),
  61. price DECIMAL(10, 2),
  62. updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  63. UNIQUE KEY idx_name (name)
  64. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  65. """
  66. cursor.execute(create_table_sql)
  67. print("[DBManager] 数据库表 douyin_products 已就绪")
  68. except Exception as e:
  69. print(f"[DBManager] 创建表失败: {e}")
  70. def search_products(self, keyword):
  71. """
  72. """
  73. conn = self.get_connection()
  74. if not conn:
  75. return []
  76. try:
  77. with conn.cursor() as cursor:
  78. # 使用关键词进行前中后模糊匹配
  79. sql = """
  80. SELECT name, stock, status, delivery_time, price
  81. FROM douyin_products
  82. WHERE name LIKE %s
  83. LIMIT 5
  84. """
  85. cursor.execute(sql, (f"%{keyword}%",))
  86. results = cursor.fetchall()
  87. return results
  88. except Exception as e:
  89. print(f"[DBManager] 搜索商品失败: {e}")
  90. return []
  91. def upsert_product(self, product_data):
  92. """
  93. product_data: dict {name, img_url, stock, status, delivery_time, price}
  94. """
  95. conn = self.get_connection()
  96. if not conn:
  97. return False # 连接失败,直接返回,不抛异常导致主程序崩溃
  98. try:
  99. with conn.cursor() as cursor:
  100. sql = """
  101. INSERT INTO douyin_products (name, img_url, stock, status, delivery_time, price, updated_at)
  102. VALUES (%s, %s, %s, %s, %s, %s, %s)
  103. ON DUPLICATE KEY UPDATE
  104. img_url = VALUES(img_url),
  105. stock = VALUES(stock),
  106. status = VALUES(status),
  107. delivery_time = VALUES(delivery_time),
  108. price = VALUES(price),
  109. updated_at = VALUES(updated_at)
  110. """
  111. cursor.execute(sql, (
  112. product_data['name'][:250], # 强制截断,防止数据库 Data too long 报错
  113. product_data['img_url'],
  114. product_data['stock'],
  115. product_data['status'],
  116. product_data['delivery_time'],
  117. product_data.get('price', 0),
  118. datetime.now()
  119. ))
  120. return True
  121. except Exception as e:
  122. print(f"[DBManager] 写入数据失败: {e}")
  123. return False
  124. if __name__ == "__main__":
  125. # 测试连接
  126. db = DBManager()
  127. test_data = {
  128. 'name': '测试商品',
  129. 'img_url': 'http://test.com/img.jpg',
  130. 'stock': 100,
  131. 'status': '现货',
  132. 'delivery_time': '48小时发货',
  133. 'price': 9.9
  134. }
  135. if db.upsert_product(test_data):
  136. print("测试写入成功")