Featured image of post 用 DuckDB 搭建自动日报系统,每月多赚 5000 元

用 DuckDB 搭建自动日报系统,每月多赚 5000 元

手把手教你用 DuckDB + Python 搭建自动化日报系统,连接 MySQL/PostgreSQL 自动聚合数据、生成图表、推送报告,打造可复售的数据产品,实现副业收入。

用 DuckDB 搭建自动日报系统,每月多赚 5000 元

在数据分析行业,最值钱的不是会写 SQL,而是把重复劳动变成自动化产品。今天拆解一个真实可落地的副业项目:用 DuckDB + Python 搭建自动日报系统,卖给中小企业,每月收订阅费。

DuckDB 自动日报系统架构图

项目背景与商业逻辑

很多中小企业每天需要统计销售、流量、转化率等核心指标,但要么老板自己瞎看 Excel,要么雇一个助理手工导出。你的机会在于:帮他们搭一个全自动系统,每天自动产出报表并推送到微信/邮件/Telegram 群。

传统方案 vs DuckDB 方案

传统方案

  • 数据导出到本地 Excel
  • 用 Excel 或手动写 VBA 处理
  • 耗时数小时,容易出错
  • 每次都要人工介入

DuckDB 方案

  • 直接连接数据库,原地计算
  • Python 脚本自动调度
  • 1-2 秒完成百万行聚合
  • 零人工介入,7x24 运行

这个方案的核心优势是原地计算——DuckDB 可以直接连接 MySQL、PostgreSQL、SQLite 等数据源,无需把数据全量搬回本地,百万行聚合在内存中 1-2 秒完成。

系统架构

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  MySQL/PG   │────▶│  DuckDB      │────▶│  Python     │
│  数据源     │     │  计算引擎     │     │  调度 & 推送 │
└─────────────┘     └──────────────┘     └─────────────┘
                                              │
                                      ┌───────▼───────┐
                                      │  邮件/Telegram │
                                      └───────────────┘

核心架构很简单:

  • 数据源:MySQL / PostgreSQL / CSV 文件
  • 计算引擎:DuckDB(秒级处理百万行数据)
  • 调度层:Python schedule 库
  • 输出:Markdown + 图片,推送到 Telegram 群或邮箱

第一步:连接数据源,用 DuckDB 做聚合计算

假设你接入了一个电商系统的订单表,数据量约 50 万行。用 DuckDB 做日级别汇总,只需要几行代码:

import duckdb
from datetime import datetime, timedelta

# 直接连接 MySQL,无需导出到本地
con = duckdb.connect('mysql://user:***@host:3306/shop', read_only=True)

# 7日汇总分析
daily_report = con.execute("""
    SELECT 
        DATE(order_time) AS dt,
        COUNT(*) AS orders,
        SUM(amount) AS revenue,
        AVG(amount) AS avg_order_value,
        COUNT(DISTINCT user_id) AS active_users
    FROM orders
    WHERE order_time >= CURRENT_DATE - INTERVAL '7 days'
    GROUP BY DATE(order_time)
    ORDER BY dt DESC
""").fetchdf()

print(daily_report)

关键技巧:DuckDB 支持原生连接多种数据库,连接字符串格式统一。MySQL 需要安装 duckdb-mysql 扩展,PostgreSQL 同理。如果数据量不大,也可以直接读 CSV 文件:duckdb.read_csv('orders.csv')

执行结果示例:

           dt  orders   revenue  avg_order_value  active_users
0  2026-08-01   1250  89500.00        71.60           890
1  2026-07-31   1180  82300.00        69.75           845
2  2026-07-30   1320  95600.00        72.42           920
...

第二步:生成可视化图表

有了数据后,用 Matplotlib 生成图表:

import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Agg')  # 无头模式,服务器友好

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# 左图:7日营收趋势
axes[0].plot(daily_report['dt'], daily_report['revenue'], 
             marker='o', color='#2E86AB', linewidth=2)
axes[0].fill_between(daily_report['dt'], daily_report['revenue'], 
                     alpha=0.2, color='#2E86AB')
axes[0].set_title('7-Day Revenue Trend')
axes[0].set_xlabel('Date')
axes[0].set_ylabel('Revenue (¥)')
axes[0].tick_params(axis='x', rotation=45)

# 右图:订单量 vs 客单价散点图(气泡大小=活跃用户数)
scatter = axes[1].scatter(
    daily_report['orders'], 
    daily_report['avg_order_value'], 
    s=daily_report['active_users'] * 2, 
    alpha=0.6, 
    c=daily_report['revenue'],
    cmap='viridis'
)
axes[1].set_title('Orders vs Avg Order Value')
axes[1].set_xlabel('Order Count')
axes[1].set_ylabel('Avg Order Value')
plt.colorbar(scatter, ax=axes[1], label='Revenue')

plt.tight_layout()
plt.savefig('/tmp/daily_report.png', dpi=120, bbox_inches='tight')

第三步:组装日报并推送

from datetime import datetime
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def format_report(df):
    """将 DataFrame 格式化为可读的日报文本"""
    today = df.iloc[0]
    yesterday = df.iloc[1] if len(df) > 1 else None
    
    report = f"""📊 今日销售日报 · {today['dt'].strftime('%Y-%m-%d')}

营收:¥{today['revenue']:,.2f}
订单数:{int(today['orders'])}客单价:¥{today['avg_order_value']:.2f}
活跃用户:{int(today['active_users'])}
"""
    if yesterday is not None:
        rev_change = (today['revenue'] - yesterday['revenue']) / yesterday['revenue'] * 100
        sign = '📈' if rev_change > 0 else '📉'
        report += f"⚡ 环比昨日:{sign} {abs(rev_change):.1f}%"
    
    return report

def send_report(report_text, image_path):
    """发送邮件(可替换为 Telegram Bot API)"""
    msg = MIMEMultipart()
    msg['Subject'] = f"日报 · {datetime.now().strftime('%m-%d')}"
    msg.attach(MIMEText(report_text, 'plain', 'utf-8'))
    
    with open(image_path, 'rb') as f:
        from email.mime.image import MIMEImage
        img = MIMEImage(f.read())
        img.add_header('Content-ID', '<report>')
        msg.attach(img)
    
    # smtp 发送逻辑省略,替换为你自己的配置
    print(f"Report ready → {image_path}")
    print(report_text)

# 执行
report_text = format_report(daily_report)
send_report(report_text, '/tmp/daily_report.png')

替换为 Telegram Bot 推送

如果觉得邮件不够即时,可以改用 Telegram Bot API:

import requests

def send_telegram(chat_id, text, photo_path=None):
    bot_token = "YOUR_BOT_TOKEN"
    url = f"https://api.telegram.org/bot{bot_token}"
    
    # 发送文本
    requests.post(f"{url}/sendMessage", json={
        "chat_id": chat_id,
        "text": text,
        "parse_mode": "HTML"
    })
    
    # 发送图片
    if photo_path:
        with open(photo_path, 'rb') as f:
            requests.post(f"{url}/sendPhoto", json={"chat_id": chat_id}, files={"photo": f})

第四步:定时调度 + 多客户隔离

import schedule
import time

def generate_daily_report(client_id):
    """为单个客户生成日报"""
    con = duckdb.connect(f'mysql://user:***@host:3306/{client_id}', read_only=True)
    # ... 执行查询、生成图表、发送报告 ...
    con.close()

# 每天 9:00 自动生成
schedule.every().day.at("09:00").do(generate_daily_report, client_id="client_001")
schedule.every().day.at("09:05").do(generate_daily_report, client_id="client_002")
schedule.every().day.at("09:10").do(generate_daily_report, client_id="client_003")

# 72小时轮询,低负载
while True:
    schedule.run_pending()
    time.sleep(60)

每个客户一个独立的 DuckDB 连接配置,报表内容按客户 ID 过滤,代码复用率极高。

DuckDB vs 传统方案的对比

维度传统 Excel/VBA 方案DuckDB + Python 方案
数据处理速度分钟级(大数据量卡死)秒级(百万行聚合 1-2s)
数据源支持仅 CSV/ExcelMySQL、PG、SQLite、CSV、Parquet
自动化程度需要人工触发完全自动调度
维护成本高(公式易错)低(代码即文档)
可视化能力基础图表完整的 Matplotlib/Seaborn
部署成本本地电脑云服务器 1核1G 即可
扩展性差(数据大了就崩)好(支持分区、谓词下推)

商业落地建议

定价策略

版本功能月费
基础版单表日报(营收/订单/用户)99 元/月
进阶版多源聚合 + 图表 + 环比分析299 元/月
企业版实时大屏 + API 接入 + 定制报表999 元/月

获客渠道

  1. 闲鱼/淘宝:挂「定制数据报表」服务,引流到私域
  2. 技术社区:在 V2EX、即刻发技术笔记,展示效果截图
  3. 免费试用:给本地小电商免费做一期,要案例和转介绍
  4. 社群运营:在行业群里分享自动化报表截图,自然获客

成本分析

  • 服务器:阿里云/腾讯云 1核1G 约 50 元/月
  • 开发时间:首次搭建 2-3 天,后续每个新客户 1-2 小时配置
  • 维护时间:每个客户每月 < 30 分钟
  • 利润率:基础版毛利约 90%,进阶版约 95%

实际项目中,一个客户从接触到付费平均 3-5 天,维护成本极低(服务器 + DuckDB 本地运行,无第三方依赖)。

进阶方向

  • 多数据源融合:用 DuckDB 的 mysql_scanner()postgres_scanner() 同时拉取 ERP 和 CRM 数据,做客户 LTV 分析
  • 自动异常检测:用 DuckDB 内置统计函数做阈值告警,营收突降自动通知老板
  • 导出 PDF:用 reportlab 把报表转成正式 PDF,增强付费感
  • Web 化:用 Streamlit 搭建可视化看板,客户自助查询
  • Docker 部署:把整个系统打包成容器,一键部署到客户服务器

完整代码仓库

本项目已开源,包含:

  • 多数据源适配(MySQL/PostgreSQL/CSV)
  • 日报/周报/月报模板
  • Telegram Bot 推送
  • Docker 部署配置
  • 多客户隔离方案

访问 duckdblab.org 获取完整代码和技术文档。


💡 变现建议总结:这个项目的核心逻辑是「用技术换时间,用时间换收入」。一个客户月费 299 元,10 个客户就是 2990 元/月,而你的维护成本几乎为零。关键是找到有数据但不会用工具的中小企业老板——他们愿意为「省心」付费。

📖 本文的完整版(含 Docker 部署、Telegram Bot 推送、多客户模板)已发布在 duckdblab.org,直接拿去用。

学习更多 DuckDB 实战经验 → duckdblab.org

📺 Watch video tutorials → Olap Studio YouTube

Subscribe for more DuckDB & AI automation tutorials

使用 Hugo 构建
主题 StackJimmy 设计

⚠️ 本站为独立社区项目,与 DuckDB 基金会及 DuckDB 官方项目无任何从属、背书或赞助关系。

"DuckDB" 是 DuckDB 基金会的注册商标,本站仅以事实描述方式使用该名称。

本站内容仅供教育与社区推广用途,不构成任何商业服务。