Repository navigation
Expand file tree
/
Copy pathmigrate_sqlite_to_pg.py
More file actions
58 lines (46 loc) · 1.75 KB
/
Copy pathmigrate_sqlite_to_pg.py
File metadata and controls
58 lines (46 loc) · 1.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
"""One-shot: copy every row from the old SQLite jobs.db into Postgres.
Run once, after the DB is up:
docker compose up -d
python migrate_sqlite_to_pg.py
Safe to re-run — rows whose job_url already exists are skipped.
"""
import sqlite3
from pathlib import Path
import database
SQLITE_PATH = Path(__file__).parent / "jobs.db"
COLUMNS = [
"id", "first_seen_at", "scraped_at", "company_name", "job_title", "location",
"job_url", "source_url", "ats_type", "requested_title", "date_posted", "status",
"years_exp", "full_description", "detail_fetched_at", "resume_path",
"resume_generated_at", "queued", "applied_at", "notes",
]
def main() -> None:
if not SQLITE_PATH.exists():
raise SystemExit(f"No SQLite DB at {SQLITE_PATH} — nothing to migrate.")
database.init_db()
src = sqlite3.connect(SQLITE_PATH)
src.row_factory = sqlite3.Row
rows = src.execute(f"SELECT {', '.join(COLUMNS)} FROM jobs").fetchall()
src.close()
pg = database.get_db()
collist = ", ".join(COLUMNS)
placeholders = ", ".join(["%s"] * len(COLUMNS))
inserted = 0
with pg.cursor() as cur:
for r in rows:
cur.execute(
f"INSERT INTO jobs ({collist}) VALUES ({placeholders}) "
"ON CONFLICT (job_url) DO NOTHING",
tuple(r[c] for c in COLUMNS),
)
inserted += cur.rowcount
# Keep the SERIAL id sequence ahead of the imported (explicit) ids.
cur.execute(
"SELECT setval(pg_get_serial_sequence('jobs', 'id'), "
"COALESCE((SELECT MAX(id) FROM jobs), 1))"
)
pg.commit()
pg.close()
print(f"Migrated {inserted} of {len(rows)} rows (existing job_urls skipped).")
if __name__ == "__main__":
main()