Spaces:
Running
Running
Upload 3 files
Browse files- src/db_manager.py +27 -5
- src/ttc_gtfs.duckdb +2 -2
src/db_manager.py
CHANGED
|
@@ -4,9 +4,11 @@ import sys # type: ignore
|
|
| 4 |
from pathlib import Path # type: ignore
|
| 5 |
from dotenv import load_dotenv # type: ignore
|
| 6 |
|
|
|
|
| 7 |
# Add parent directory to path to allow imports from api/
|
| 8 |
sys.path.insert(0, str(Path(__file__).parent.parent))
|
| 9 |
|
|
|
|
| 10 |
from api.bus_cache import AsyncBusCache # type: ignore
|
| 11 |
|
| 12 |
# Configuration - always save DB in src/ directory
|
|
@@ -14,14 +16,34 @@ DB_PATH = str(Path(__file__).parent / "ttc_gtfs.duckdb")
|
|
| 14 |
STATIC_DIR = str(Path(__file__).parent.parent / "static")
|
| 15 |
|
| 16 |
def init_db():
|
| 17 |
-
|
|
|
|
| 18 |
|
| 19 |
-
#
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
if all(t in tables for t in ["routes", "trips", "stops", "stop_times", "shapes"]):
|
| 24 |
-
print("--- Database fully populated (including shapes) ---")
|
| 25 |
return con
|
| 26 |
|
| 27 |
print("--- Initializing/Updating DuckDB: Importing CSVs ---")
|
|
|
|
| 4 |
from pathlib import Path # type: ignore
|
| 5 |
from dotenv import load_dotenv # type: ignore
|
| 6 |
|
| 7 |
+
|
| 8 |
# Add parent directory to path to allow imports from api/
|
| 9 |
sys.path.insert(0, str(Path(__file__).parent.parent))
|
| 10 |
|
| 11 |
+
from api.update_static import GTFSSyncManager
|
| 12 |
from api.bus_cache import AsyncBusCache # type: ignore
|
| 13 |
|
| 14 |
# Configuration - always save DB in src/ directory
|
|
|
|
| 16 |
STATIC_DIR = str(Path(__file__).parent.parent / "static")
|
| 17 |
|
| 18 |
def init_db():
|
| 19 |
+
sync_mgr = GTFSSyncManager()
|
| 20 |
+
remote_data = sync_mgr.get_remote_metadata()
|
| 21 |
|
| 22 |
+
# Connect to existing or new DB
|
| 23 |
+
con = duckdb.connect(sync_mgr.DB_PATH)
|
| 24 |
+
|
| 25 |
+
# 1. Setup metadata tracking
|
| 26 |
+
con.execute("CREATE TABLE IF NOT EXISTS sync_metadata (key VARCHAR PRIMARY KEY, value VARCHAR)")
|
| 27 |
+
local_update = con.execute("SELECT value FROM sync_metadata WHERE key = 'last_modified'").fetchone()
|
| 28 |
+
|
| 29 |
+
# 2. Check if we need to sync based on API metadata
|
| 30 |
+
should_sync = False
|
| 31 |
+
if not local_update or (remote_data and remote_data["updated_at"] > local_update[0]):
|
| 32 |
+
should_sync = True
|
| 33 |
|
| 34 |
+
if should_sync and remote_data:
|
| 35 |
+
print(f"--- Data Stale. Remote: {remote_data['updated_at']} | Local: {local_update[0] if local_update else 'None'} ---")
|
| 36 |
+
con.close() # Close to allow file deletion
|
| 37 |
+
sync_mgr.perform_full_sync(remote_data["url"])
|
| 38 |
+
|
| 39 |
+
# Reconnect and finalize metadata
|
| 40 |
+
con = duckdb.connect(sync_mgr.DB_PATH)
|
| 41 |
+
con.execute("CREATE TABLE IF NOT EXISTS sync_metadata (key VARCHAR PRIMARY KEY, value VARCHAR)")
|
| 42 |
+
con.execute("INSERT OR REPLACE INTO sync_metadata VALUES ('last_modified', ?)", [remote_data["updated_at"]])
|
| 43 |
+
|
| 44 |
+
# 3. Standard Import Loop (runs if DB was nuked or is missing tables)
|
| 45 |
+
tables = [t[0] for t in con.execute("SHOW TABLES").fetchall()]
|
| 46 |
if all(t in tables for t in ["routes", "trips", "stops", "stop_times", "shapes"]):
|
|
|
|
| 47 |
return con
|
| 48 |
|
| 49 |
print("--- Initializing/Updating DuckDB: Importing CSVs ---")
|
src/ttc_gtfs.duckdb
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:816a12c5c8dca213be643f4d3d822463043e7e62044df1fc08743bfad12047d3
|
| 3 |
+
size 123219968
|