Migrate data pipeline from SQLite to PostgreSQL + Docker setup
- Add db.py PostgreSQL abstraction layer (connection, upsert, table mgmt) - Replace sqlite3 with psycopg2 in: live_candle_fetcher, resampler, data_fetcher, fetch_history, import_csv, indicators, base_strategy - Sanitize table names (colons -> underscores) for PostgreSQL compat - Replace INSERT OR REPLACE with ON CONFLICT upserts - Replace pandas to_sql() with batch upsert_candles() - Add scripts: resampler_loop, gap_detector, backup_runner, cron_scheduler - Add migrate_sqlite_to_pg.py for one-time data migration - Add Dockerfile, docker-compose.yml, supervisord.conf - Add postgres/postgresql.conf tuned for 4GB RAM (Synology DS1513+) - Add .dockerignore, .env.docker.example, secrets template - Update requirements.txt (psycopg2-binary), .gitignore - Add MIGRATION_PLAN.md with full plan and todo list
This commit is contained in:
@ -1,10 +1,10 @@
|
||||
import requests
|
||||
import json
|
||||
import sqlite3
|
||||
import db
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
|
||||
DB_PATH = "_data/market_data.db"
|
||||
DB_PATH = os.environ.get("PG_CONN_STR", "postgresql://hyper:hyper@localhost:5432/hyper")
|
||||
URL = "https://api.hyperliquid.xyz/info"
|
||||
|
||||
def fetch_historical_candles(coin, start_ms, end_ms, interval="1m"):
|
||||
@ -37,22 +37,10 @@ def fetch_historical_candles(coin, start_ms, end_ms, interval="1m"):
|
||||
|
||||
def write_candles_to_db(coin, candles, interval="1m"):
|
||||
"""Write candles to the database."""
|
||||
table_name = coin + "_" + interval
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
# Ensure table exists
|
||||
cursor.execute(f'''
|
||||
CREATE TABLE IF NOT EXISTS "{table_name}" (
|
||||
datetime_utc TEXT,
|
||||
timestamp_ms INTEGER PRIMARY KEY,
|
||||
open REAL,
|
||||
high REAL,
|
||||
low REAL,
|
||||
close REAL,
|
||||
volume REAL,
|
||||
number_of_trades INTEGER
|
||||
)
|
||||
''')
|
||||
table_name = db.sanitize_table_name(coin, interval)
|
||||
conn = db.get_connection()
|
||||
db.create_candle_table(conn, table_name)
|
||||
records = []
|
||||
for candle in candles:
|
||||
record = (
|
||||
datetime.fromtimestamp(candle['t'] / 1000, tz=timezone.utc).strftime('%Y-%m-%d %H:%M:%S'),
|
||||
@ -60,22 +48,16 @@ def write_candles_to_db(coin, candles, interval="1m"):
|
||||
candle.get('o'), candle.get('h'), candle.get('l'), candle.get('c'),
|
||||
candle.get('v'), candle.get('n')
|
||||
)
|
||||
cursor.execute(f'''
|
||||
INSERT OR REPLACE INTO "{table_name}" (datetime_utc, timestamp_ms, open, high, low, close, volume, number_of_trades)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
''', record)
|
||||
conn.commit()
|
||||
records.append(record)
|
||||
db.upsert_candles(conn, table_name, records)
|
||||
conn.close()
|
||||
|
||||
def get_last_timestamp(coin):
|
||||
"""Get the most recent timestamp from the database."""
|
||||
table_name = coin + "_1m"
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
table_name = db.sanitize_table_name(coin, "1m")
|
||||
conn = db.get_connection()
|
||||
try:
|
||||
cursor.execute(f'SELECT MAX(timestamp_ms) FROM "{table_name}"')
|
||||
result = cursor.fetchone()
|
||||
return int(result[0]) if result and result[0] is not None else None
|
||||
return db.get_last_timestamp(conn, table_name)
|
||||
except:
|
||||
return None
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user