mysql_dao.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. from core import get_logger
  2. from database import MySqlDatabaseHelper
  3. from sqlalchemy import text, bindparam
  4. import pandas as pd
  5. logger = get_logger("database.dao")
  6. class MySqlDao:
  7. _instance = None
  8. _IN_CLAUSE_BATCH_SIZE = 1000
  9. def __new__(cls):
  10. if not cls._instance:
  11. cls._instance = super(MySqlDao, cls).__new__(cls)
  12. cls._instance._initialized = False
  13. return cls._instance
  14. def __init__(self):
  15. if self._initialized:
  16. return
  17. self.db_helper = MySqlDatabaseHelper()
  18. self._product_tablename = "tads_brandcul_product_info_f"
  19. self._cust_tablename = "tads_brandcul_retail_cust_label"
  20. self._order_tablename = "tads_brandcul_consumer_order"
  21. self._eval_order_name = "tads_brandcul_consumer_order_check_week"
  22. self._order_analysis_table_name = "tads_brandcul_analysis_index" # 销售指标指标分析表
  23. self._mock_order_tablename = "yunfu_mock_data"
  24. self._shopping_tablename = "tads_brandcul_cust_info_lbs_f"
  25. # self._shopping_tablename = "yunfu_shopping_mock_data"
  26. self._report_tablename = "tads_brandcul_report"
  27. self._initialized = True
  28. def _iter_batches(self, values, batch_size=None):
  29. values = [] if values is None else list(values)
  30. batch_size = batch_size or self._IN_CLAUSE_BATCH_SIZE
  31. for i in range(0, len(values), batch_size):
  32. yield values[i:i + batch_size]
  33. def load_product_data(self, city_uuid):
  34. """从数据库中读取商品信息"""
  35. logger.info(f"Loading product data for city_uuid={city_uuid}")
  36. query = f"SELECT * FROM {self._product_tablename} WHERE city_uuid = :city_uuid AND org_is_active = '是'"
  37. params = {"city_uuid": city_uuid}
  38. data = self.db_helper.load_data_with_page(query, params)
  39. return data
  40. def load_cust_data(self, city_uuid):
  41. """从数据库中读取商户信息"""
  42. logger.info(f"Loading cust data for city_uuid={city_uuid}")
  43. query = f"SELECT * FROM {self._cust_tablename} WHERE corp_uuid = :city_uuid"
  44. params = {"city_uuid": city_uuid}
  45. data = self.db_helper.load_data_with_page(query, params)
  46. return data
  47. def load_order_data(self, city_uuid):
  48. """从数据库中读取订单信息"""
  49. logger.info(f"Loading order data for city_uuid={city_uuid}")
  50. query = f"SELECT * FROM {self._order_tablename} WHERE city_uuid = :city_uuid"
  51. params = {"city_uuid": city_uuid}
  52. data = self.db_helper.load_data_with_page(query, params)
  53. data.drop('stat_month', axis=1, inplace=True)
  54. data.drop('city_uuid', axis=1, inplace=True)
  55. cust_list = self.get_cust_list(city_uuid)
  56. cust_index = cust_list.set_index("cust_code")
  57. data = data.join(cust_index, on="cust_code", how="inner")
  58. return data
  59. def load_order_analysis_index_data(self, city_uuid):
  60. """从数据库中读取销售指标评估表"""
  61. logger.info(f"Loading order analysis index data for city_uuid={city_uuid}")
  62. query = f"SELECT * FROM {self._order_analysis_table_name} WHERE city_uuid = :city_uuid"
  63. params = {"city_uuid": city_uuid}
  64. data = self.db_helper.load_data_with_page(query, params)
  65. return data
  66. def load_delivery_order_data(self, city_uuid, start_time, end_time):
  67. """从数据库中读取订单信息"""
  68. logger.info(f"Loading delivery order data for city_uuid={city_uuid}, start_time={start_time}, end_time={end_time}")
  69. query = f"SELECT * FROM {self._eval_order_name} WHERE city_uuid = :city_uuid AND cycle_begin_date = :start_time AND cycle_end_date = :end_time"
  70. params = {
  71. "city_uuid": city_uuid,
  72. "start_time": start_time,
  73. "end_time": end_time
  74. }
  75. data = self.db_helper.load_data_with_page(query, params)
  76. return data
  77. def load_mock_order_data(self):
  78. """从数据库中读取mock的订单信息"""
  79. logger.info("Loading mock order data")
  80. query = f"SELECT * FROM {self._mock_order_tablename}"
  81. data = self.db_helper.load_data_with_page(query, {})
  82. return data
  83. def load_shopping_data(self, city_uuid):
  84. """从数据库中读取商圈数据"""
  85. logger.info(f"Loading shopping data for city_uuid={city_uuid}")
  86. query = f"SELECT * FROM {self._shopping_tablename} WHERE city_uuid = :city_uuid"
  87. params = {"city_uuid": city_uuid}
  88. data = self.db_helper.load_data_with_page(query, params)
  89. return data
  90. def get_product_by_id(self, city_uuid, product_id):
  91. """根据city_uuid 和 product_id 从表中获取拼柜信息"""
  92. logger.info(f"Getting product by id for city_uuid={city_uuid}, product_id={product_id}")
  93. query = text(f"""
  94. SELECT *
  95. FROM {self._product_tablename}
  96. WHERE city_uuid = :city_uuid
  97. AND product_code = :product_id
  98. """)
  99. params = {"city_uuid": city_uuid, "product_id": product_id}
  100. result = self.db_helper.fetch_one(query, params)
  101. return pd.DataFrame([dict(result._mapping)] if result else [])
  102. def get_cust_by_ids(self, city_uuid, cust_id_list):
  103. """根据零售户列表查询其信息"""
  104. logger.info(f"Getting cust by ids for city_uuid={city_uuid}, count={len(cust_id_list) if cust_id_list else 0}")
  105. if not cust_id_list:
  106. return pd.DataFrame()
  107. results = []
  108. for batch in self._iter_batches(cust_id_list):
  109. query = text(f"""
  110. SELECT *
  111. FROM {self._cust_tablename}
  112. WHERE corp_uuid = :city_uuid
  113. AND cust_code IN :ids
  114. """).bindparams(bindparam("ids", expanding=True))
  115. params = {"city_uuid": city_uuid, "ids": batch}
  116. results.append(pd.DataFrame(self.db_helper.fetch_all(query, params)))
  117. return pd.concat(results, ignore_index=True) if results else pd.DataFrame()
  118. def get_shop_by_ids(self, city_uuid, cust_id_list):
  119. """根据零售户列表查询其信息"""
  120. logger.info(f"Getting shop by ids for city_uuid={city_uuid}, count={len(cust_id_list) if cust_id_list else 0}")
  121. if not cust_id_list:
  122. return pd.DataFrame()
  123. results = []
  124. for batch in self._iter_batches(cust_id_list):
  125. query = text(f"""
  126. SELECT *
  127. FROM {self._shopping_tablename}
  128. WHERE city_uuid = :city_uuid
  129. AND cust_code IN :ids
  130. """).bindparams(bindparam("ids", expanding=True))
  131. params = {"city_uuid": city_uuid, "ids": batch}
  132. results.append(pd.DataFrame(self.db_helper.fetch_all(query, params)))
  133. return pd.concat(results, ignore_index=True) if results else pd.DataFrame()
  134. def get_product_by_ids(self, city_uuid, product_id_list):
  135. """根据product_code列表查询其信息"""
  136. logger.info(f"Getting products by ids for city_uuid={city_uuid}, count={len(product_id_list) if product_id_list else 0}")
  137. if not product_id_list:
  138. return pd.DataFrame()
  139. results = []
  140. for batch in self._iter_batches(product_id_list):
  141. query = text(f"""
  142. SELECT *
  143. FROM {self._product_tablename}
  144. WHERE city_uuid = :city_uuid
  145. AND product_code IN :ids
  146. ORDER BY product_code
  147. """).bindparams(bindparam("ids", expanding=True))
  148. params = {"city_uuid": city_uuid, "ids": batch}
  149. results.append(pd.DataFrame(self.db_helper.fetch_all(query, params)))
  150. return pd.concat(results, ignore_index=True) if results else pd.DataFrame()
  151. def get_order_by_product_ids(self, city_uuid, product_ids):
  152. """获取指定香烟列表的所有售卖记录"""
  153. logger.info(f"Getting orders by product ids for city_uuid={city_uuid}, count={len(product_ids) if product_ids else 0}")
  154. if not product_ids:
  155. return pd.DataFrame()
  156. results = []
  157. for batch in self._iter_batches(product_ids):
  158. query = text(f"""
  159. SELECT *
  160. FROM {self._order_tablename}
  161. WHERE city_uuid = :city_uuid
  162. AND product_code IN :ids
  163. ORDER BY cust_code, product_code
  164. """).bindparams(bindparam("ids", expanding=True))
  165. params = {"city_uuid": city_uuid, "ids": batch}
  166. results.append(pd.DataFrame(self.db_helper.fetch_all(query, params)))
  167. data = pd.concat(results, ignore_index=True) if results else pd.DataFrame()
  168. cust_list = self.get_cust_list(city_uuid)
  169. cust_index = cust_list.set_index("cust_code")
  170. data = data.join(cust_index, on="cust_code", how="inner")
  171. return data
  172. def get_order_by_cust_ids_and_product_ids(self, city_uuid, cust_id_list, product_ids):
  173. """获取指定商户列表在指定品规列表上的售卖记录"""
  174. logger.info(f"Getting orders by cust ids and product ids for city_uuid={city_uuid}, custs={len(cust_id_list)}, products={len(product_ids)}")
  175. if not cust_id_list or not product_ids:
  176. return pd.DataFrame()
  177. results = []
  178. for cust_batch in self._iter_batches(cust_id_list):
  179. for product_batch in self._iter_batches(product_ids):
  180. query = text(f"""
  181. SELECT cust_code, product_code, sale_qty
  182. FROM {self._order_tablename}
  183. WHERE city_uuid = :city_uuid
  184. AND cust_code IN :cust_ids
  185. AND product_code IN :product_ids
  186. """).bindparams(bindparam("cust_ids", expanding=True), bindparam("product_ids", expanding=True))
  187. params = {
  188. "city_uuid": city_uuid,
  189. "cust_ids": cust_batch,
  190. "product_ids": product_batch,
  191. }
  192. results.append(pd.DataFrame(self.db_helper.fetch_all(query, params)))
  193. return pd.concat(results, ignore_index=True) if results else pd.DataFrame()
  194. def get_order_by_product(self, city_uuid, product_id):
  195. logger.info(f"Getting orders by product for city_uuid={city_uuid}, product_id={product_id}")
  196. query = f"""
  197. SELECT *
  198. FROM {self._order_tablename}
  199. WHERE city_uuid = :city_uuid
  200. AND product_code = :product_id
  201. """
  202. params = {"city_uuid": city_uuid, "product_id": product_id}
  203. data = self.db_helper.load_data_with_page(query, params)
  204. cust_list = self.get_cust_list(city_uuid)
  205. cust_index = cust_list.set_index("cust_code")
  206. data = data.join(cust_index, on="cust_code", how="inner")
  207. return data
  208. def get_eval_order_by_product(self, city_uuid, product_id):
  209. logger.info(f"Getting eval orders by product for city_uuid={city_uuid}, product_id={product_id}")
  210. query = f"""
  211. SELECT *
  212. FROM {self._eval_order_name}
  213. WHERE city_uuid = :city_uuid
  214. AND product_code = :product_id
  215. """
  216. params = {"city_uuid": city_uuid, "product_id": product_id}
  217. data = self.db_helper.load_data_with_page(query, params)
  218. return data
  219. def get_delivery_data_by_product(self, city_uuid, product_id, start_time, end_time):
  220. """通过品规获取验证数据"""
  221. logger.info(f"Getting delivery data by product for city_uuid={city_uuid}, product_id={product_id}, start_time={start_time}, end_time={end_time}")
  222. query = f"""
  223. SELECT *
  224. FROM {self._eval_order_name}
  225. WHERE city_uuid = :city_uuid
  226. AND goods_code = :product_id
  227. AND cycle_begin_date = :start_time
  228. AND cycle_end_date = :end_time
  229. """
  230. params = {
  231. "city_uuid": city_uuid,
  232. "product_id": product_id,
  233. "start_time": start_time,
  234. "end_time": end_time,
  235. }
  236. data = self.db_helper.load_data_with_page(query, params)
  237. return data
  238. def get_order_by_cust(self, city_uuid, cust_id):
  239. logger.info(f"Getting orders by cust for city_uuid={city_uuid}, cust_id={cust_id}")
  240. query = f"""
  241. SELECT *
  242. FROM {self._order_tablename}
  243. WHERE city_uuid = :city_uuid
  244. AND cust_code = :cust_id
  245. """
  246. params = {"city_uuid": city_uuid, "cust_id": cust_id}
  247. data = self.db_helper.load_data_with_page(query, params)
  248. return data
  249. def get_order_by_cust_and_product(self, city_uuid, cust_id, product_id):
  250. logger.info(f"Getting orders by cust and product for city_uuid={city_uuid}, cust_id={cust_id}, product_id={product_id}")
  251. query = f"""
  252. SELECT *
  253. FROM {self._order_tablename}
  254. WHERE city_uuid = :city_uuid
  255. AND cust_code = :cust_id
  256. AND product_code =:product_id
  257. """
  258. params = {"city_uuid": city_uuid, "cust_id": cust_id, "product_id": product_id}
  259. data = self.db_helper.load_data_with_page(query, params)
  260. return data
  261. def get_product_from_order(self, city_uuid):
  262. logger.info(f"Getting products from order for city_uuid={city_uuid}")
  263. query = f"SELECT DISTINCT product_code FROM {self._order_tablename} WHERE city_uuid = :city_uuid ORDER BY product_code"
  264. params = {"city_uuid": city_uuid}
  265. data = self.db_helper.load_data_with_page(query, params)
  266. return data
  267. def get_cust_list(self, city_uuid):
  268. logger.info(f"Getting cust list for city_uuid={city_uuid}")
  269. query = f"SELECT DISTINCT cust_code FROM {self._cust_tablename} WHERE corp_uuid = :city_uuid ORDER BY cust_code"
  270. params = {"city_uuid": city_uuid}
  271. data = self.db_helper.load_data_with_page(query, params)
  272. return data
  273. def insert_report(self, data_dict):
  274. """向report中插入数据"""
  275. logger.info("Inserting report data")
  276. return self.db_helper.insert_data(self._report_tablename, data_dict)
  277. def update_eval_report_data(self, cultivacation_id, eval_fileid):
  278. """更新投放记录中的验证报告fileid"""
  279. logger.info(f"Updating eval report data for cultivacation_id={cultivacation_id}")
  280. update_data = {"val_table": eval_fileid}
  281. conditions = [
  282. "cultivacation_id = :cultivacation_id",
  283. ]
  284. condition_params = {
  285. 'cultivacation_id': cultivacation_id,
  286. }
  287. self.db_helper.update_data(self._report_tablename, update_data, conditions, condition_params)
  288. def get_report_file_id(self, cultivacation_id):
  289. """从report中根据cultivacation_id获取对应文件的fileid"""
  290. logger.info(f"Getting report file id for cultivacation_id={cultivacation_id}")
  291. query = f"SELECT product_info_table, relation_table, similarity_product_table, recommend_table, val_table FROM {self._report_tablename} WHERE cultivacation_id = :cultivacation_id"
  292. params = {"cultivacation_id": cultivacation_id}
  293. result = self.db_helper.fetch_one(text(query), params)
  294. if result is None:
  295. logger.warning(f"No report found for cultivacation_id={cultivacation_id}")
  296. return pd.DataFrame()
  297. return pd.DataFrame([dict(result._mapping)])
  298. if __name__ == "__main__":
  299. dao = MySqlDao()
  300. city_uuid = '00000000000000000000000011445301'
  301. data = dao.load_order_data(city_uuid)
  302. print(data)