dwd_build.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. DWD 层明细宽表计算任务
  5. 说明:在 Doris 内部关联 ODS 表生成就诊明细事实表
  6. """
  7. import datetime
  8. from db.pool import get_doris_conn
  9. from logger.handler import get_logger
  10. logger = get_logger("job.dwd_patient_exam")
  11. def run(start_date=None, end_date=None):
  12. """执行 DWD 层计算"""
  13. if start_date is None or end_date is None:
  14. yesterday = datetime.date.today() - datetime.timedelta(days=1)
  15. start_date = end_date = yesterday.strftime("%Y-%m-%d")
  16. logger.info("=" * 60)
  17. logger.info(f"[DWD计算] 开始计算: {start_date}")
  18. logger.info("=" * 60)
  19. conn = get_doris_conn()
  20. cursor = conn.cursor()
  21. try:
  22. # 先清空当天的数据(幂等性)
  23. delete_sql = """
  24. DELETE FROM fact_patient_exam_detail
  25. WHERE data_date = %s
  26. """
  27. cursor.execute(delete_sql, [start_date])
  28. affected_rows = cursor.rowcount
  29. if affected_rows > 0:
  30. logger.info(f"清理旧数据: {affected_rows} 条")
  31. conn.commit()
  32. # 执行计算 SQL
  33. build_sql = get_build_sql(start_date)
  34. logger.info("开始执行计算...")
  35. cursor.execute(build_sql)
  36. affected_rows = cursor.rowcount
  37. conn.commit()
  38. logger.info("=" * 60)
  39. logger.info(f"[DWD计算] 计算完成: {affected_rows} 条")
  40. logger.info("=" * 60)
  41. return affected_rows
  42. except Exception as e:
  43. logger.error(f"[DWD计算] 计算失败: {e}")
  44. conn.rollback()
  45. raise
  46. finally:
  47. cursor.close()
  48. conn.close()
  49. def get_build_sql(data_date):
  50. """生成计算 SQL"""
  51. return f"""
  52. INSERT INTO fact_patient_exam_detail (
  53. id,
  54. patient_id,
  55. patient_id_str,
  56. patient_name,
  57. sex,
  58. age,
  59. birthday,
  60. mobile,
  61. identity,
  62. clinic_id,
  63. come_time,
  64. come_date,
  65. visit_type,
  66. channel,
  67. goods_id,
  68. goods_name,
  69. goods_uuid,
  70. fee_class,
  71. pickup_id,
  72. pickup_time,
  73. pickup_date,
  74. order_id,
  75. orderdetail_id,
  76. pay_time,
  77. pay_date,
  78. pay_amt,
  79. refund_time,
  80. org_id,
  81. org_name,
  82. group_id,
  83. group_name,
  84. customer_optometrist_staff_id,
  85. customer_optometrist_name,
  86. customer_optometrist_org_name,
  87. accept_doctor_id,
  88. accept_doctor_name,
  89. accept_optometrist_id,
  90. accept_optometrist_name,
  91. exam_result_json,
  92. exam_tab,
  93. exam_id,
  94. right_se_val,
  95. left_se_val,
  96. right_sph_val,
  97. left_sph_val,
  98. right_cyl_val,
  99. left_cyl_val,
  100. al_od_val,
  101. al_os_val,
  102. data_date,
  103. create_time,
  104. update_time
  105. )
  106. SELECT
  107. c.id,
  108. p.id as patient_id,
  109. p.patientId as patient_id_str,
  110. p.name as patient_name,
  111. CASE WHEN p.sex = '男' THEN 1 ELSE 2 END as sex,
  112. TIMESTAMPDIFF(YEAR, p.birthday, CURDATE()) as age,
  113. p.birthday,
  114. p.mobile,
  115. p.identity,
  116. c.id as clinic_id,
  117. c.come_time,
  118. DATE(c.come_time) as come_date,
  119. c.type as visit_type,
  120. c.channel,
  121. g.id as goods_id,
  122. g.name as goods_name,
  123. g.uuid_no as goods_uuid,
  124. g.fee_class,
  125. sg.id as pickup_id,
  126. sg.out_time as pickup_time,
  127. DATE(sg.out_time) as pickup_date,
  128. fo.id as order_id,
  129. fod.id as orderdetail_id,
  130. fo.pay_time,
  131. DATE(fo.pay_time) as pay_date,
  132. fod.quantity * fod.price as pay_amt,
  133. r.refund_time,
  134. c.org_id,
  135. org.name as org_name,
  136. org.group_id,
  137. grp.name as group_name,
  138. p.customer_optometrist_staff_id,
  139. s.name as customer_optometrist_name,
  140. s_org.name as customer_optometrist_org_name,
  141. c.accept_doctor_id,
  142. d.name as accept_doctor_name,
  143. c.accept_optometrist_id,
  144. o.name as accept_optometrist_name,
  145. er.result as exam_result_json,
  146. er.tab as exam_tab,
  147. er.exam_id,
  148. NULL as right_se_val,
  149. NULL as left_se_val,
  150. NULL as right_sph_val,
  151. NULL as left_sph_val,
  152. NULL as right_cyl_val,
  153. NULL as left_cyl_val,
  154. NULL as al_od_val,
  155. NULL as al_os_val,
  156. DATE(c.come_time) as data_date,
  157. NOW() as create_time,
  158. NOW() as update_time
  159. FROM ods_clinic_clinic c
  160. JOIN ods_patient_custome p ON c.patient_id = p.id
  161. LEFT JOIN ods_org_org org ON c.org_id = org.id
  162. LEFT JOIN ods_fee_order fo ON fo.patientId = p.patientId
  163. AND DATE(fo.pay_time) = '{data_date}'
  164. LEFT JOIN ods_fee_orderdetail fod ON fod.order_id = fo.id
  165. LEFT JOIN ods_material_goods g ON g.id = fod.goods_id
  166. LEFT JOIN ods_treat_sellgoods sg ON sg.sell_goods_list_id = fod.sell_goods_list_id
  167. LEFT JOIN ods_fee_refunddetail r ON r.orderdetail_id = fod.id
  168. LEFT JOIN ods_staff_staff s ON s.id = p.customer_optometrist_staff_id
  169. LEFT JOIN ods_org_org s_org ON s.main_org_id = s_org.id
  170. LEFT JOIN ods_staff_staff d ON d.id = c.accept_doctor_id
  171. LEFT JOIN ods_staff_staff o ON o.id = c.accept_optometrist_id
  172. LEFT JOIN ods_exam_examresult er ON er.clinic_id = c.id
  173. AND er.tab IN ('yj_dnyg', 'tj_gxsw')
  174. LEFT JOIN ods_org_group grp ON grp.id = org.group_id
  175. WHERE c.come_time >= '{data_date} 00:00:00'
  176. AND c.come_time < '{data_date} 23:59:59'
  177. AND c.reg_status IN (1, 2, 3, 4)
  178. AND c.pno = ''
  179. AND org.is_effective = 1
  180. AND g.fee_class IN ('长期治疗类', '离焦镜片')
  181. """