@@ -32,23 +32,32 @@ def parse_ts(value):
3232 return datetime .strptime (value , "%Y-%m-%d %H:%M:%S" ).replace (tzinfo = timezone .utc )
3333
3434
35- # (table_name, columns in migration order, columns that need SQLite-text -> datetime parsing)
35+ # (table_name, columns in migration order, columns that need SQLite-text -> datetime
36+ # parsing, order-by column for the SELECT). Tables keyed by stock_code (no surrogate
37+ # `id` column) pass has_id=False so no identity-sequence fixup is attempted.
3638TABLES = [
37- ("holdings_snapshot" , ["id" , "stock_code" , "quantity" , "average_price" , "current_price" , "timestamp" ], ["timestamp" ]),
38- ("watchlist" , ["id" , "stock_code" ], []),
39- ("ohlcv_cache" , ["id" , "stock_code" , "date" , "open" , "high" , "low" , "close" , "volume" ], []),
39+ ("holdings_snapshot" , ["id" , "stock_code" , "quantity" , "average_price" , "current_price" , "timestamp" ], ["timestamp" ], "id" , True ),
40+ ("watchlist" , ["id" , "stock_code" ], [], "id" , True ),
41+ ("ohlcv_cache" , ["id" , "stock_code" , "date" , "open" , "high" , "low" , "close" , "volume" ], [], "id" , True ),
4042 ("signals" , ["id" , "stock_code" , "rsi14" , "macd_line" , "macd_signal" , "sma50" , "sma200" ,
41- "pct_from_52w_high" , "volume_ratio_20d" , "composite_score" , "timestamp" ], ["timestamp" ]),
42- ("job_heartbeats" , ["id" , "job_name" , "timestamp" ], ["timestamp" ]),
43- ("session_tokens" , ["id" , "token" , "timestamp" ], ["timestamp" ]),
44- ("refresh_requests" , ["id" , "requested_at" , "processed_at" ], ["requested_at" , "processed_at" ]),
45- ("stage_history" , ["id" , "stock_code" , "date" , "stage" , "sma_150" , "slope" ], []),
46- ("stock_actions" , ["id" , "stock_code" , "action" , "rationale" , "timestamp" ], ["timestamp" ]),
43+ "pct_from_52w_high" , "volume_ratio_20d" , "composite_score" , "timestamp" ], ["timestamp" ], "id" , True ),
44+ ("job_heartbeats" , ["id" , "job_name" , "timestamp" ], ["timestamp" ], "id" , True ),
45+ ("session_tokens" , ["id" , "token" , "timestamp" ], ["timestamp" ], "id" , True ),
46+ ("refresh_requests" , ["id" , "requested_at" , "processed_at" ], ["requested_at" , "processed_at" ], "id" , True ),
47+ ("stage_history" , ["id" , "stock_code" , "date" , "stage" , "sma_150" , "slope" ], [], "id" , True ),
48+ ("stock_actions" , ["id" , "stock_code" , "action" , "rationale" , "timestamp" ], ["timestamp" ], "id" , True ),
49+ ("ticker_mapping" , ["stock_code" , "nse_symbol" , "isin" , "resolved_at" ], ["resolved_at" ], "stock_code" , False ),
50+ ("backfill_requests" , ["id" , "stock_code" , "requested_at" , "processed_at" , "status" , "error" ],
51+ ["requested_at" , "processed_at" ], "id" , True ),
52+ ("data_health" , ["id" , "stock_code" , "source" , "status" , "message" , "timestamp" ], ["timestamp" ], "id" , True ),
53+ ("portfolio_value_history" , ["id" , "timestamp" , "total_invested" , "total_current_value" , "total_pnl" ],
54+ ["timestamp" ], "id" , True ),
55+ ("stock_metadata" , ["stock_code" , "sector" , "industry" , "updated_at" ], ["updated_at" ], "stock_code" , False ),
4756]
4857
4958
50- async def migrate_table (pg_conn , sqlite_conn , table , columns , ts_columns , truncate ):
51- cur = sqlite_conn .execute (f"SELECT { ', ' .join (columns )} FROM { table } ORDER BY id " )
59+ async def migrate_table (pg_conn , sqlite_conn , table , columns , ts_columns , order_col , has_id , truncate ):
60+ cur = sqlite_conn .execute (f"SELECT { ', ' .join (columns )} FROM { table } ORDER BY { order_col } " )
5261 rows = cur .fetchall ()
5362
5463 if truncate :
@@ -69,10 +78,11 @@ async def migrate_table(pg_conn, sqlite_conn, table, columns, ts_columns, trunca
6978 insert_sql = f"INSERT INTO { table } ({ ', ' .join (columns )} ) VALUES ({ placeholders } )"
7079 await pg_conn .executemany (insert_sql , processed_rows )
7180
72- await pg_conn .execute (
73- f"SELECT setval(pg_get_serial_sequence('{ table } ', 'id'), "
74- f"COALESCE((SELECT MAX(id) FROM { table } ), 0) + 1, false)"
75- )
81+ if has_id :
82+ await pg_conn .execute (
83+ f"SELECT setval(pg_get_serial_sequence('{ table } ', 'id'), "
84+ f"COALESCE((SELECT MAX(id) FROM { table } ), 0) + 1, false)"
85+ )
7686
7787 logger .info (f"{ table } : migrated { len (rows )} rows" )
7888 return len (rows )
@@ -99,8 +109,8 @@ async def main():
99109
100110 try :
101111 total = 0
102- for table , columns , ts_columns in TABLES :
103- total += await migrate_table (pg_conn , sqlite_conn , table , columns , ts_columns , args .truncate )
112+ for table , columns , ts_columns , order_col , has_id in TABLES :
113+ total += await migrate_table (pg_conn , sqlite_conn , table , columns , ts_columns , order_col , has_id , args .truncate )
104114 logger .info (f"Migration complete. { total } total row(s) migrated across { len (TABLES )} tables." )
105115 finally :
106116 sqlite_conn .close ()
0 commit comments