代码优化
This commit is contained in:
+1
-1
@@ -131,7 +131,7 @@ def run(start_date, end_date, token):
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="同步交易日历")
|
parser = argparse.ArgumentParser(description="同步交易日历")
|
||||||
parser.add_argument("--start-date", default="20260430", help="开始日期,格式 YYYYMMDD")
|
parser.add_argument("--start-date", default="20260430", help="开始日期,格式 YYYYMMDD")
|
||||||
parser.add_argument("--end-date", default="20260430", help="结束日期,格式 YYYYMMDD")
|
parser.add_argument("--end-date", default="20260506", help="结束日期,格式 YYYYMMDD")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
run(args.start_date, args.end_date, TUSHARE_TOKEN)
|
run(args.start_date, args.end_date, TUSHARE_TOKEN)
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ def run(start_date, end_date):
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="同步日行情")
|
parser = argparse.ArgumentParser(description="同步日行情")
|
||||||
parser.add_argument("--start-date", default="20260430", help="开始日期,格式 YYYYMMDD")
|
parser.add_argument("--start-date", default="20260430", help="开始日期,格式 YYYYMMDD")
|
||||||
parser.add_argument("--end-date", default="20260430", help="结束日期,格式 YYYYMMDD")
|
parser.add_argument("--end-date", default="20260506", help="结束日期,格式 YYYYMMDD")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
run(args.start_date, args.end_date)
|
run(args.start_date, args.end_date)
|
||||||
|
|||||||
+74
-12
@@ -49,13 +49,14 @@ def filter_dates_by_start(trade_dates, start_date, source_name):
|
|||||||
return filtered_dates
|
return filtered_dates
|
||||||
|
|
||||||
|
|
||||||
def init_db(engine):
|
def init_db(engine, full_maintenance=False):
|
||||||
"""
|
"""
|
||||||
初始化数据库表结构
|
初始化数据库表结构
|
||||||
"""
|
"""
|
||||||
with engine.begin() as conn:
|
with engine.begin() as conn:
|
||||||
|
print(f" - 确保 {COMBINED_TABLE} 存在 ...")
|
||||||
conn.execute(text(get_combined_table_sql()))
|
conn.execute(text(get_combined_table_sql()))
|
||||||
optimize_combined_table(conn)
|
optimize_combined_table(conn, full_maintenance=full_maintenance)
|
||||||
|
|
||||||
|
|
||||||
def get_combined_table_sql():
|
def get_combined_table_sql():
|
||||||
@@ -106,6 +107,22 @@ def get_table_columns(conn, table_name):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_column_collation(conn, table_name, column_name):
|
||||||
|
row = conn.execute(
|
||||||
|
text(
|
||||||
|
"""
|
||||||
|
SELECT collation_name
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = DATABASE()
|
||||||
|
AND table_name = :table_name
|
||||||
|
AND column_name = :column_name
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
{"table_name": table_name, "column_name": column_name},
|
||||||
|
).first()
|
||||||
|
return row[0] if row else None
|
||||||
|
|
||||||
|
|
||||||
def index_exists(conn, table_name, index_name):
|
def index_exists(conn, table_name, index_name):
|
||||||
return conn.execute(
|
return conn.execute(
|
||||||
text(
|
text(
|
||||||
@@ -166,6 +183,27 @@ def ensure_combined_columns(conn):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ensure_combined_join_collation(conn)
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_combined_join_collation(conn):
|
||||||
|
daily_collation = get_column_collation(conn, "stock_daily", "ts_code")
|
||||||
|
combined_collation = get_column_collation(conn, COMBINED_TABLE, "ts_code")
|
||||||
|
if not daily_collation or not combined_collation or daily_collation == combined_collation:
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f" - 对齐 ts_code collation:{combined_collation} -> {daily_collation} ...")
|
||||||
|
conn.execute(
|
||||||
|
text(
|
||||||
|
f"""
|
||||||
|
ALTER TABLE `{COMBINED_TABLE}`
|
||||||
|
MODIFY `ts_code` VARCHAR(20)
|
||||||
|
CHARACTER SET utf8mb4 COLLATE {daily_collation}
|
||||||
|
NOT NULL COMMENT 'TS股票代码,以stock_daily为准'
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def sync_combined_vol_from_daily(conn):
|
def sync_combined_vol_from_daily(conn):
|
||||||
conn.execute(
|
conn.execute(
|
||||||
@@ -173,8 +211,8 @@ def sync_combined_vol_from_daily(conn):
|
|||||||
f"""
|
f"""
|
||||||
UPDATE `{COMBINED_TABLE}` c
|
UPDATE `{COMBINED_TABLE}` c
|
||||||
JOIN `stock_daily` d
|
JOIN `stock_daily` d
|
||||||
ON c.trade_date = d.trade_date
|
ON c.ts_code = d.ts_code
|
||||||
AND c.ts_code COLLATE utf8mb4_unicode_ci = d.ts_code COLLATE utf8mb4_unicode_ci
|
AND c.trade_date = d.trade_date
|
||||||
SET c.symbol = d.symbol,
|
SET c.symbol = d.symbol,
|
||||||
c.calc_vol = d.vol
|
c.calc_vol = d.vol
|
||||||
"""
|
"""
|
||||||
@@ -189,8 +227,8 @@ def dedupe_combined_table(conn):
|
|||||||
DELETE c
|
DELETE c
|
||||||
FROM `{COMBINED_TABLE}` c
|
FROM `{COMBINED_TABLE}` c
|
||||||
LEFT JOIN `stock_daily` d
|
LEFT JOIN `stock_daily` d
|
||||||
ON c.trade_date = d.trade_date
|
ON c.ts_code = d.ts_code
|
||||||
AND c.ts_code COLLATE utf8mb4_unicode_ci = d.ts_code COLLATE utf8mb4_unicode_ci
|
AND c.trade_date = d.trade_date
|
||||||
WHERE d.ts_code IS NULL
|
WHERE d.ts_code IS NULL
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
@@ -202,7 +240,7 @@ def dedupe_combined_table(conn):
|
|||||||
FROM `{COMBINED_TABLE}` c1
|
FROM `{COMBINED_TABLE}` c1
|
||||||
JOIN `{COMBINED_TABLE}` c2
|
JOIN `{COMBINED_TABLE}` c2
|
||||||
ON c1.trade_date = c2.trade_date
|
ON c1.trade_date = c2.trade_date
|
||||||
AND c1.ts_code COLLATE utf8mb4_unicode_ci = c2.ts_code COLLATE utf8mb4_unicode_ci
|
AND c1.ts_code = c2.ts_code
|
||||||
WHERE
|
WHERE
|
||||||
(
|
(
|
||||||
COALESCE(c1.source_count, 0) * 10
|
COALESCE(c1.source_count, 0) * 10
|
||||||
@@ -236,16 +274,30 @@ def dedupe_combined_table(conn):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def ensure_combined_indexes(conn):
|
def ensure_combined_indexes(conn, full_maintenance=False):
|
||||||
|
needs_unique_rebuild = index_exists(
|
||||||
|
conn, COMBINED_TABLE, "uniq_date_code"
|
||||||
|
) and not index_matches(
|
||||||
|
conn, COMBINED_TABLE, "uniq_date_code", ["trade_date", "ts_code"], unique=True
|
||||||
|
)
|
||||||
|
needs_unique_create = not index_matches(
|
||||||
|
conn, COMBINED_TABLE, "uniq_date_code", ["trade_date", "ts_code"], unique=True
|
||||||
|
)
|
||||||
|
|
||||||
|
if full_maintenance or needs_unique_rebuild or needs_unique_create:
|
||||||
|
print(" - 清理历史重复/无效融合数据 ...")
|
||||||
dedupe_combined_table(conn)
|
dedupe_combined_table(conn)
|
||||||
|
|
||||||
if index_exists(conn, COMBINED_TABLE, "uniq_date_code") and not index_matches(
|
if index_exists(conn, COMBINED_TABLE, "uniq_date_code") and not index_matches(
|
||||||
conn, COMBINED_TABLE, "uniq_date_code", ["trade_date", "ts_code"], unique=True
|
conn, COMBINED_TABLE, "uniq_date_code", ["trade_date", "ts_code"], unique=True
|
||||||
):
|
):
|
||||||
|
print(" - 重建 uniq_date_code 唯一索引 ...")
|
||||||
conn.execute(text(f"ALTER TABLE `{COMBINED_TABLE}` DROP INDEX `uniq_date_code`"))
|
conn.execute(text(f"ALTER TABLE `{COMBINED_TABLE}` DROP INDEX `uniq_date_code`"))
|
||||||
|
|
||||||
if not index_matches(
|
if not index_matches(
|
||||||
conn, COMBINED_TABLE, "uniq_date_code", ["trade_date", "ts_code"], unique=True
|
conn, COMBINED_TABLE, "uniq_date_code", ["trade_date", "ts_code"], unique=True
|
||||||
):
|
):
|
||||||
|
print(" - 创建 uniq_date_code 唯一索引 ...")
|
||||||
conn.execute(
|
conn.execute(
|
||||||
text(
|
text(
|
||||||
f"ALTER TABLE `{COMBINED_TABLE}` "
|
f"ALTER TABLE `{COMBINED_TABLE}` "
|
||||||
@@ -253,14 +305,17 @@ def ensure_combined_indexes(conn):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
if not index_exists(conn, COMBINED_TABLE, "idx_trade_date"):
|
if not index_exists(conn, COMBINED_TABLE, "idx_trade_date"):
|
||||||
|
print(" - 创建 idx_trade_date 索引 ...")
|
||||||
conn.execute(
|
conn.execute(
|
||||||
text(f"ALTER TABLE `{COMBINED_TABLE}` ADD KEY `idx_trade_date` (`trade_date`)")
|
text(f"ALTER TABLE `{COMBINED_TABLE}` ADD KEY `idx_trade_date` (`trade_date`)")
|
||||||
)
|
)
|
||||||
if not index_exists(conn, COMBINED_TABLE, "idx_symbol"):
|
if not index_exists(conn, COMBINED_TABLE, "idx_symbol"):
|
||||||
|
print(" - 创建 idx_symbol 索引 ...")
|
||||||
conn.execute(
|
conn.execute(
|
||||||
text(f"ALTER TABLE `{COMBINED_TABLE}` ADD KEY `idx_symbol` (`symbol`)")
|
text(f"ALTER TABLE `{COMBINED_TABLE}` ADD KEY `idx_symbol` (`symbol`)")
|
||||||
)
|
)
|
||||||
if not index_exists(conn, COMBINED_TABLE, "idx_trade_date_status"):
|
if not index_exists(conn, COMBINED_TABLE, "idx_trade_date_status"):
|
||||||
|
print(" - 创建 idx_trade_date_status 索引 ...")
|
||||||
conn.execute(
|
conn.execute(
|
||||||
text(
|
text(
|
||||||
f"ALTER TABLE `{COMBINED_TABLE}` "
|
f"ALTER TABLE `{COMBINED_TABLE}` "
|
||||||
@@ -269,10 +324,17 @@ def ensure_combined_indexes(conn):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def optimize_combined_table(conn):
|
def optimize_combined_table(conn, full_maintenance=False):
|
||||||
|
print(" - 检查字段 ...")
|
||||||
ensure_combined_columns(conn)
|
ensure_combined_columns(conn)
|
||||||
|
if full_maintenance:
|
||||||
|
print(" - 从 stock_daily 全量回填 calc_vol ...")
|
||||||
sync_combined_vol_from_daily(conn)
|
sync_combined_vol_from_daily(conn)
|
||||||
ensure_combined_indexes(conn)
|
else:
|
||||||
|
print(" - 跳过全量 calc_vol 回填,当前批次写入时会直接带入 vol。")
|
||||||
|
print(" - 检查索引 ...")
|
||||||
|
ensure_combined_indexes(conn, full_maintenance=full_maintenance)
|
||||||
|
print(" - 校验重复键 ...")
|
||||||
validate_no_duplicate_combined_rows(conn)
|
validate_no_duplicate_combined_rows(conn)
|
||||||
|
|
||||||
|
|
||||||
@@ -711,7 +773,7 @@ def analyze_and_save_limits(start_date, end_date):
|
|||||||
def cleanup_combined_data():
|
def cleanup_combined_data():
|
||||||
engine = get_engine()
|
engine = get_engine()
|
||||||
try:
|
try:
|
||||||
init_db(engine)
|
init_db(engine, full_maintenance=True)
|
||||||
print(f"✅ {COMBINED_TABLE} 已完成历史重复数据清理、唯一索引检查和 calc_vol 回填。")
|
print(f"✅ {COMBINED_TABLE} 已完成历史重复数据清理、唯一索引检查和 calc_vol 回填。")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -725,7 +787,7 @@ def cleanup_combined_data():
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="计算并保存涨停/炸板数据")
|
parser = argparse.ArgumentParser(description="计算并保存涨停/炸板数据")
|
||||||
parser.add_argument("--start-date", default="2026-04-30", help="开始日期,格式 YYYY-MM-DD,实际查询为大于该日期")
|
parser.add_argument("--start-date", default="2026-04-30", help="开始日期,格式 YYYY-MM-DD,实际查询为大于该日期")
|
||||||
parser.add_argument("--end-date", default="2026-04-30", help="结束日期,格式 YYYY-MM-DD")
|
parser.add_argument("--end-date", default="2026-05-06", help="结束日期,格式 YYYY-MM-DD")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--cleanup-only",
|
"--cleanup-only",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
|
|||||||
Reference in New Issue
Block a user