waliullah123 commited on
Commit
e9d657c
·
verified ·
1 Parent(s): 0429685

Upload db.py

Browse files
Files changed (1) hide show
  1. db.py +65 -0
db.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ db.py — Database abstraction layer.
3
+
4
+ - Production (HF Spaces): set DATABASE_URL env var → uses Neon PostgreSQL via psycopg2
5
+ - Local dev: no DATABASE_URL → falls back to SQLite
6
+
7
+ Usage in other modules:
8
+ from db import get_conn, PH, IntegrityError
9
+
10
+ conn = get_conn()
11
+ cursor = conn.cursor()
12
+ cursor.execute(f"SELECT * FROM users WHERE username = {PH}", (username,))
13
+ row = cursor.fetchone()
14
+ conn.close()
15
+ """
16
+
17
+ import os
18
+ import sqlite3
19
+ import logging
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+ # Connection string from environment (set as HF Space Secret)
24
+ DATABASE_URL = os.environ.get('DATABASE_URL', '')
25
+
26
+ # Are we using PostgreSQL?
27
+ USE_POSTGRES = bool(DATABASE_URL)
28
+
29
+ if USE_POSTGRES:
30
+ import psycopg2
31
+ import psycopg2.extras
32
+ import psycopg2.errors
33
+ # Placeholder style for PostgreSQL
34
+ PH = '%s'
35
+ # Exception alias
36
+ IntegrityError = psycopg2.errors.UniqueViolation
37
+ logger.info("DB: Using Neon PostgreSQL")
38
+ else:
39
+ # Placeholder style for SQLite
40
+ PH = '?'
41
+ # Exception alias
42
+ IntegrityError = sqlite3.IntegrityError
43
+ logger.info("DB: Using local SQLite (dev mode)")
44
+
45
+ # SQLite path (only used in local dev)
46
+ _SQLITE_PATH = os.path.join(os.path.dirname(__file__), 'data', 'users.db')
47
+
48
+
49
+ def get_conn():
50
+ """
51
+ Returns an open database connection.
52
+ Caller is responsible for calling conn.close() (use finally blocks).
53
+ """
54
+ if USE_POSTGRES:
55
+ if 'sslmode=' not in DATABASE_URL:
56
+ conn = psycopg2.connect(DATABASE_URL, sslmode='require')
57
+ else:
58
+ conn = psycopg2.connect(DATABASE_URL)
59
+ conn.autocommit = False
60
+ return conn
61
+ else:
62
+ os.makedirs(os.path.dirname(_SQLITE_PATH), exist_ok=True)
63
+ conn = sqlite3.connect(_SQLITE_PATH, timeout=10)
64
+ conn.execute('PRAGMA busy_timeout=5000')
65
+ return conn