AlphaFeed Blog

如何把 A 股数据存进 SQLite?增量 upsert + SQL 查询(零额外依赖)

工程化 · 代码验证于 2026-10-19

如何把 A 股数据存进 SQLite?(增量 upsert + SQL 查询)

一句话回答: 用 Python 标准库 sqlite3(零额外依赖)就能把 AlphaFeed 的 K 线存成本地库:建表时用 (symbol, trade_date) 做主键,写入用 INSERT OR REPLACE 实现幂等增量更新(重复写不会产生重复行、还能覆盖修正),之后用 SQL 任意查询。相比 CSV/Parquet 文件,SQLite 单文件、支持索引与 SQL 过滤聚合,特别适合”增量累积 + 频繁按条件查”的本地行情库。

为什么会有这个问题 / 传统做法的痛点

把每天的行情往 CSV 里追加,很快就遇到:重复写入产生重复行、要按日期/代码筛选得全量读进内存、多表 join 困难。SQLite 是嵌入式数据库,一个文件搞定,天然支持主键去重、索引、SQL 聚合,还不用起服务。痛点仅在于:很多人不知道用复合主键 + INSERT OR REPLACE 就能优雅实现幂等增量,于是手写各种”先查再插”的笨办法。

分步骤解决(每步配可运行代码)

第 1 步:取数据 + 建表(复合主键)

from alphafeed import AlphaFeed
import sqlite3

af = AlphaFeed(api_key="your-api-key")  # 或 export ALPHAFEED_API_KEY 后 AlphaFeed()

data = af.klines.batch(["600519.SH", "000001.SZ"], period="1d",
                       count=60, adjust="forward", to_dataframe=True)

con = sqlite3.connect("market.db")
con.execute("""CREATE TABLE IF NOT EXISTS klines(
    symbol TEXT, trade_date TEXT,
    open REAL, high REAL, low REAL, close REAL, volume REAL, amount REAL,
    PRIMARY KEY(symbol, trade_date))""")      # 复合主键 = 幂等去重的关键

第 2 步:幂等增量写入(INSERT OR REPLACE)

def upsert(con, df):
    cols = ["symbol","trade_date","open","high","low","close","volume","amount"]
    rows = df[cols].values.tolist()
    con.executemany("""INSERT OR REPLACE INTO klines
        (symbol,trade_date,open,high,low,close,volume,amount)
        VALUES(?,?,?,?,?,?,?,?)""", rows)
    con.commit()

for sym, k in data.items():
    upsert(con, k)

INSERT OR REPLACE 命中主键就覆盖、不命中就插入——同一天的数据重复写只会有一行,天天跑也不会重复。

第 3 步:验证幂等 + 用 SQL 查询

n1 = con.execute("SELECT COUNT(*) FROM klines").fetchone()[0]
for sym, k in data.items(): upsert(con, k)        # 再写一次
n2 = con.execute("SELECT COUNT(*) FROM klines").fetchone()[0]
print("行数:", n1, "→", n2, "(相等=幂等)")

rows = con.execute("""SELECT trade_date, close FROM klines
    WHERE symbol='600519.SH' ORDER BY trade_date DESC LIMIT 5""").fetchall()
print(rows)

实测(tools/verify_new_2026-10-19.py,SDK 0.1.4):写入 2 只股票各 60 天共 120 行,重复写入后仍是 120 行(幂等 ✅),SELECT ... LIMIT 5 正确返回茅台最近 5 日收盘。

参数与字段说明

参数/概念含义备注
adjust="forward"前复权建议存原始价+因子或固定复权口径,见下
PRIMARY KEY(symbol, trade_date)复合主键幂等去重的核心
INSERT OR REPLACE命中主键则覆盖幂等增量
executemany批量写比逐行快很多
索引主键自带索引按 symbol/date 查很快

关键坑与注意事项

常见问题(FAQ)

Q:SQLite 和 Parquet 怎么选? A:Parquet 适合”一次写、列式批量分析”的大文件;SQLite 适合”持续增量 + 频繁按条件/多表 SQL 查询”的本地库。两者可共存:SQLite 做主库,导出 Parquet 给分析。

Q:会不会很慢? A:日频、几千只股票十年数据对 SQLite 毫无压力;给常用查询建索引即可。真正到达瓶颈(亿级行、高并发)再考虑 DuckDB/Postgres。

Q:需要付费吗? A:单只/少量日线在免费额度内即可;要批量灌全市场建库,需要 klines.batch + universes(Starter 及以上),详见官网定价页。

小结

用标准库 sqlite3 + (symbol, trade_date) 复合主键 + INSERT OR REPLACE,几行就能把 AlphaFeed 的 K 线存成幂等增量的本地行情库,再用 SQL 任意查询。记住固定复权口径(推荐存原始价+因子)、trade_date 存文本、批量用事务、单进程更新最稳。

相关链接:


免责声明:本文仅为技术与数据接口使用示例,代码与策略仅供学习研究,不构成投资建议。市场有风险,历史数据不代表未来表现。