mengtaoguo commited on
Commit
fd4a31c
·
verified ·
1 Parent(s): 465f3b5

Update quality_audit_job.py

Browse files
Files changed (1) hide show
  1. quality_audit_job.py +37 -65
quality_audit_job.py CHANGED
@@ -4,22 +4,23 @@ import time
4
  import sys
5
  import logging
6
  from supabase import create_client
7
- # from dotenv import load_dotenv
8
 
9
- # 强制不缓存输出,确保进度条能实时显示
10
- logging.basicConfig(
11
- level=logging.INFO,
12
- format='%(message)s', # 简化格式让进度条更美观
13
- stream=sys.stdout
14
- )
15
  logger = logging.getLogger(__name__)
16
 
17
- # load_dotenv()
 
 
 
18
 
19
- supabase = create_client(os.environ.get("SUPABASE_URL"), os.environ.get("SUPABASE_SERVICE_KEY"))
 
 
20
 
21
- def get_progress_bar(current, total, bar_length=40):
22
- """生成字符进度条"""
 
23
  fraction = current / total if total > 0 else 0
24
  arrow = int(fraction * bar_length) * '█'
25
  padding = (bar_length - len(arrow)) * '░'
@@ -30,81 +31,52 @@ def analyze_text(text):
30
  is_empty = text_str.startswith("[Empty") or len(text_str) == 0
31
  char_count = len(text_str)
32
  has_garbage = bool(re.search(r'[ÂÃÅÐÑÒÓÔÕÖר]', text_str))
33
-
34
  score = 100
35
- tags = []
36
- if is_empty:
37
- score = 0; tags.append("no_data")
38
  else:
39
- if char_count < 50: score -= 30; tags.append("short")
40
- if has_garbage: score -= 20; tags.append("dirty_html")
41
-
42
- return {
43
- "is_filled": not is_empty,
44
- "is_empty_placeholder": is_empty,
45
- "is_null": text is None,
46
- "char_count": char_count,
47
- "word_count": len(text_str.split()),
48
- "has_garbage_chars": has_garbage,
49
- "quality_score": score,
50
- "issue_tags": tags
51
- }
52
 
53
  def run_audit():
54
- # 1. 获取主表总记录 (用于计算进度)
55
- count_res = supabase.table("bs4_plants").select("id", count="exact").execute()
56
- total_count = count_res.count if count_res.count else 7038
57
-
58
- logger.info(f"🚀 启动审计引擎 | 目标数据量: {total_count} 条")
59
- fields = ['edible_uses', 'medicinal_uses', 'cultivation_details']
60
 
61
  while True:
62
  try:
63
- # 2. 获取当前审计表已处理的植物数量 (去重计数)
64
- # 注意:因为一个植物3个字段,我们按 plant_id 分组统计
65
- current_audit_res = supabase.rpc("get_audited_count").execute()
66
- processed_count = current_audit_res.data if current_audit_res.data else 0
67
 
68
  # 打印进度条
69
- bar = get_progress_bar(processed_count, total_count)
70
- logger.info(f"📊 进度: {bar} ({processed_count}/{total_count})")
71
 
72
- # 3. 获取水位线
73
- last_audit_res = supabase.table("data_quality_audit") \
74
- .select("updated_at") \
75
- .order("updated_at", desc=True) \
76
- .limit(1).execute()
77
-
78
- last_time = last_audit_res.data[0]['updated_at'] if last_audit_res.data else "1970-01-01T00:00:00Z"
79
 
80
- # 4. 抓取变动 (每次50条)
81
- res = supabase.table("bs4_plants") \
82
- .select("plant_id, edible_uses, medicinal_uses, cultivation_details, updated_at") \
83
- .gt("updated_at", last_time) \
84
- .order("updated_at", desc=False) \
85
- .limit(50).execute()
86
 
87
  if not res.data:
88
- if processed_count >= total_count:
89
- logger.info("✨ 100% 完成!正在监听增量更新...")
90
- time.sleep(300)
91
- else:
92
- logger.info("⌛ 正在同步中,请稍候...")
93
- time.sleep(30)
94
  continue
95
 
96
  for row in res.data:
97
- for field in fields:
98
- analysis = analyze_text(row.get(field))
99
  supabase.table("data_quality_audit").upsert({
100
- "plant_id": row['plant_id'],
101
- "field_name": field,
102
- **analysis,
103
  "updated_at": "now()"
104
  }).execute()
105
 
106
  except Exception as e:
107
- logger.error(f"❌ 运行异常: {str(e)}")
108
  time.sleep(10)
109
 
110
  if __name__ == "__main__":
 
4
  import sys
5
  import logging
6
  from supabase import create_client
 
7
 
8
+ # 强制不缓存输出
9
+ logging.basicConfig(level=logging.INFO, format='%(message)s', stream=sys.stdout)
 
 
 
 
10
  logger = logging.getLogger(__name__)
11
 
12
+ # --- 核心修正点:匹配你截图里的变量名 ---
13
+ url = os.environ.get("SUPABASE_URL")
14
+ # 尝试读取截图中的 SERVICE_ROLE_KEY
15
+ key = os.environ.get("SUPABASE_SERVICE_ROLE_KEY")
16
 
17
+ if not url or not key:
18
+ print(f"❌ 环境变量缺失! URL: {'OK' if url else 'MISSING'}, KEY: {'OK' if key else 'MISSING'}", flush=True)
19
+ sys.exit(1)
20
 
21
+ supabase = create_client(url, key)
22
+
23
+ def get_progress_bar(current, total, bar_length=30):
24
  fraction = current / total if total > 0 else 0
25
  arrow = int(fraction * bar_length) * '█'
26
  padding = (bar_length - len(arrow)) * '░'
 
31
  is_empty = text_str.startswith("[Empty") or len(text_str) == 0
32
  char_count = len(text_str)
33
  has_garbage = bool(re.search(r'[ÂÃÅÐÑÒÓÔÕÖר]', text_str))
 
34
  score = 100
35
+ if is_empty: score = 0
 
 
36
  else:
37
+ if char_count < 50: score -= 30
38
+ if has_garbage: score -= 20
39
+ return {"is_filled": not is_empty, "char_count": char_count, "has_garbage_chars": has_garbage, "quality_score": score}
 
 
 
 
 
 
 
 
 
 
40
 
41
  def run_audit():
42
+ # 你的据湖大小
43
+ total_count = 7038
44
+ logger.info(f"🚀 审计引擎启动 | 目标量: {total_count}", flush=True)
 
 
 
45
 
46
  while True:
47
  try:
48
+ # --- 修正点:不使用 RPC,改用普通 COUNT ---
49
+ # 个植物审计3个字段,所以 count / 3
50
+ count_res = supabase.table("data_quality_audit").select("id", count="exact").execute()
51
+ processed_plants = (count_res.count or 0) // 3
52
 
53
  # 打印进度条
54
+ print(f"📊 进度: {get_progress_bar(processed_plants, total_count)} ({processed_plants}/{total_count})", flush=True)
 
55
 
56
+ # 水位线逻辑
57
+ last_res = supabase.table("data_quality_audit").select("updated_at").order("updated_at", desc=True).limit(1).execute()
58
+ last_time = last_res.data[0]['updated_at'] if last_res.data else "1970-01-01T00:00:00Z"
 
 
 
 
59
 
60
+ # 抓取主表变动
61
+ res = supabase.table("bs4_plants").select("plant_id, edible_uses, medicinal_uses, cultivation_details, updated_at")\
62
+ .gt("updated_at", last_time).order("updated_at").limit(20).execute()
 
 
 
63
 
64
  if not res.data:
65
+ time.sleep(30)
 
 
 
 
 
66
  continue
67
 
68
  for row in res.data:
69
+ for f in ['edible_uses', 'medicinal_uses', 'cultivation_details']:
70
+ analysis = analyze_text(row.get(f))
71
  supabase.table("data_quality_audit").upsert({
72
+ "plant_id": row['plant_id'],
73
+ "field_name": f,
74
+ **analysis,
75
  "updated_at": "now()"
76
  }).execute()
77
 
78
  except Exception as e:
79
+ print(f"❌ 运行异常: {e}", flush=True)
80
  time.sleep(10)
81
 
82
  if __name__ == "__main__":