import pandas as pd import psycopg2 from psycopg2.extras import RealDictCursor # 数据库连接配置 conn = psycopg2.connect( host="bj-postgres-16pob4sg.sql.tencentcdb.com", port=28591, user="ai_member", password="LdfjdjL83h3h3^$&**YGG*", dbname="vala_bi" ) user_ids = [51, 17690, 17646, 2705] # 1. 查询用户注册信息 query_register = """ SELECT id as user_id, created_at as register_time, status as user_status, tel as user_mobile FROM bi_vala_app_account WHERE id IN %s """ df_register = pd.read_sql(query_register, conn, params=(tuple(user_ids),)) # 2. 查询用户购课情况 query_purchase = """ SELECT account_id as user_id, COUNT(*) as purchased_course_count, SUM(pay_amount_int)/100.0 as total_paid_amount, MAX(created_at) as last_purchase_time FROM bi_vala_order WHERE account_id IN %s AND pay_amount_int > 0 GROUP BY account_id """ df_purchase = pd.read_sql(query_purchase, conn, params=(tuple(user_ids),)) # 3. 查询用户学习进度 query_learn = """ SELECT account_id as user_id, course_level, latest_unit_index as current_unit, latest_lesson_index as current_lesson, learn_duration as total_learn_seconds, last_learn_time FROM bi_user_course_detail WHERE account_id IN %s """ df_learn = pd.read_sql(query_learn, conn, params=(tuple(user_ids),)) # 合并数据 df_result = df_register.merge(df_purchase, on='user_id', how='left') df_result = df_result.merge(df_learn, on='user_id', how='left') # 填充空值 df_result = df_result.fillna({ 'purchased_course_count': 0, 'total_paid_amount': 0, 'learning_course_count': 0, 'average_progress_percent': 0 }) # 格式化时间列 df_result['register_time'] = df_result['register_time'].dt.strftime('%Y-%m-%d %H:%M:%S') df_result['last_purchase_time'] = pd.to_datetime(df_result['last_purchase_time']).dt.strftime('%Y-%m-%d %H:%M:%S') df_result['last_learn_time'] = pd.to_datetime(df_result['last_learn_time']).dt.strftime('%Y-%m-%d %H:%M:%S') # 导出为Excel output_path = '/root/.openclaw/workspace/用户详细信息.xlsx' df_result.to_excel(output_path, index=False, sheet_name='用户信息') print(f"文件已生成:{output_path}") print("数据预览:") print(df_result.to_csv(sep='\t', na_rep='无')) conn.close()