amaye15 commited on
Commit
24dc858
·
1 Parent(s): 465ba2d

Debug - DB

Browse files
Files changed (1) hide show
  1. app/database.py +47 -24
app/database.py CHANGED
@@ -2,7 +2,8 @@
2
  import os
3
  from databases import Database
4
  from dotenv import load_dotenv
5
- from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, text
 
6
  import logging
7
  from urllib.parse import urlparse, urlunparse, parse_qs, urlencode
8
 
@@ -10,12 +11,10 @@ load_dotenv()
10
  logger = logging.getLogger(__name__)
11
 
12
  # --- Database URL Configuration ---
13
- # --- CHANGE THIS LINE: Use the /tmp directory ---
14
  DEFAULT_DB_PATH = "/tmp/app.db" # Store DB in the temporary directory
15
-
16
  raw_db_url = os.getenv("DATABASE_URL", f"sqlite+aiosqlite:///{DEFAULT_DB_PATH}")
17
 
18
- # --- (Rest of the URL parsing and async Database setup remains the same) ---
19
  final_database_url = raw_db_url
20
  if raw_db_url.startswith("sqlite+aiosqlite"):
21
  parsed_url = urlparse(raw_db_url)
@@ -46,49 +45,73 @@ engine = create_engine(sync_db_url)
46
  # --- Directory and Table Creation Logic ---
47
  db_file_path = ""
48
  if sync_db_url.startswith("sqlite"):
49
- # Path should be absolute starting with /tmp/
50
  path_part = sync_db_url.split("sqlite:///")[-1].split("?")[0]
51
  db_file_path = path_part # Should be /tmp/app.db
52
 
53
  if db_file_path:
54
- # --- CHANGE THIS LINE: Check writability of the /tmp directory ---
55
  db_dir = os.path.dirname(db_file_path) # Should be /tmp
56
- logger.info(f"Ensuring database directory exists: {db_dir}")
57
  try:
58
- # /tmp should always exist, but check writability
59
  if not os.path.exists(db_dir):
60
- # This would be very strange, but log it.
61
  logger.error(f"CRITICAL: Directory {db_dir} does not exist!")
62
- # No need to create /tmp usually
63
-
64
- if not os.access(db_dir, os.W_OK):
65
- # If even /tmp isn't writable, something is very wrong with the environment
66
  logger.error(f"CRITICAL: Directory {db_dir} is not writable! Cannot create database.")
67
  else:
68
  logger.info(f"Database directory {db_dir} appears writable.")
69
-
70
  except OSError as e:
71
  logger.error(f"Error accessing database directory {db_dir}: {e}")
72
  except Exception as e:
73
  logger.error(f"Unexpected error checking directory {db_dir}: {e}")
74
 
75
- # --- (Rest of the table creation logic and async functions remain the same) ---
 
76
  try:
77
- logger.info("Attempting to connect with sync engine to check/create table...")
78
  with engine.connect() as connection:
 
79
  try:
 
80
  connection.execute(text("SELECT 1 FROM users LIMIT 1"))
81
- logger.info("Users table already exists.")
82
- except Exception as table_check_exc:
83
- logger.warning(f"Users table check failed ({type(table_check_exc).__name__}), attempting creation...")
84
- metadata.create_all(bind=engine)
85
- logger.info("Users table created (or creation attempted).")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  except Exception as e:
88
- # This *should* finally succeed if /tmp is writable
89
- logger.exception(f"CRITICAL: Failed to connect/create database tables using sync engine: {e}")
 
90
 
91
- # Async connect/disconnect functions
92
  async def connect_db():
93
  try:
94
  await database.connect()
 
2
  import os
3
  from databases import Database
4
  from dotenv import load_dotenv
5
+ # --- ADD THIS IMPORT ---
6
+ from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, text, exc as sqlalchemy_exc
7
  import logging
8
  from urllib.parse import urlparse, urlunparse, parse_qs, urlencode
9
 
 
11
  logger = logging.getLogger(__name__)
12
 
13
  # --- Database URL Configuration ---
 
14
  DEFAULT_DB_PATH = "/tmp/app.db" # Store DB in the temporary directory
 
15
  raw_db_url = os.getenv("DATABASE_URL", f"sqlite+aiosqlite:///{DEFAULT_DB_PATH}")
16
 
17
+ # --- URL Parsing and Async Database setup (remains the same) ---
18
  final_database_url = raw_db_url
19
  if raw_db_url.startswith("sqlite+aiosqlite"):
20
  parsed_url = urlparse(raw_db_url)
 
45
  # --- Directory and Table Creation Logic ---
46
  db_file_path = ""
47
  if sync_db_url.startswith("sqlite"):
 
48
  path_part = sync_db_url.split("sqlite:///")[-1].split("?")[0]
49
  db_file_path = path_part # Should be /tmp/app.db
50
 
51
  if db_file_path:
 
52
  db_dir = os.path.dirname(db_file_path) # Should be /tmp
53
+ logger.info(f"Checking database directory: {db_dir}")
54
  try:
 
55
  if not os.path.exists(db_dir):
 
56
  logger.error(f"CRITICAL: Directory {db_dir} does not exist!")
57
+ elif not os.access(db_dir, os.W_OK):
 
 
 
58
  logger.error(f"CRITICAL: Directory {db_dir} is not writable! Cannot create database.")
59
  else:
60
  logger.info(f"Database directory {db_dir} appears writable.")
 
61
  except OSError as e:
62
  logger.error(f"Error accessing database directory {db_dir}: {e}")
63
  except Exception as e:
64
  logger.error(f"Unexpected error checking directory {db_dir}: {e}")
65
 
66
+
67
+ # --- Refined Synchronous Table Check/Creation ---
68
  try:
69
+ logger.info("Attempting sync connection to check/create table...")
70
  with engine.connect() as connection:
71
+ logger.info("Sync engine connection successful.")
72
  try:
73
+ # Check if table exists
74
  connection.execute(text("SELECT 1 FROM users LIMIT 1"))
75
+ logger.info("Users table already exists (checked via sync connection).")
76
+ # --- Catch specific SQLAlchemy error ---
77
+ except sqlalchemy_exc.OperationalError as table_missing_err:
78
+ # Check if the error message specifically indicates "no such table"
79
+ if "no such table" in str(table_missing_err).lower():
80
+ logger.warning("Users table not found (expected), attempting creation...")
81
+ try:
82
+ # Begin a transaction explicitly (optional, connect() usually does)
83
+ # with connection.begin(): # Alternative way to manage transaction
84
+ # Use the connection object for create_all
85
+ metadata.create_all(bind=connection) # <-- Bind to connection
86
+ # --- Explicitly commit ---
87
+ connection.commit()
88
+ logger.info("Users table creation attempted and committed via sync connection.")
89
+ # --- Verify creation immediately ---
90
+ try:
91
+ connection.execute(text("SELECT 1 FROM users LIMIT 1"))
92
+ logger.info("Users table successfully verified immediately after creation.")
93
+ except Exception as verify_err:
94
+ logger.error(f"Failed to verify table immediately after creation: {verify_err}")
95
+
96
+ except Exception as creation_err:
97
+ logger.exception(f"Error during table creation or commit: {creation_err}")
98
+ # Optionally rollback? connection.rollback()
99
+
100
+ else:
101
+ # Log other OperationalErrors during the check phase
102
+ logger.error(f"OperationalError during table check (but not 'no such table'): {table_missing_err}")
103
+ raise # Re-raise unexpected errors
104
+
105
+ except Exception as table_check_exc: # Catch other unexpected errors during check
106
+ logger.error(f"Unexpected error during table check: {type(table_check_exc).__name__}: {table_check_exc}")
107
+ raise # Re-raise unexpected errors
108
 
109
  except Exception as e:
110
+ # Errors connecting, or unexpected errors during check/create phase
111
+ logger.exception(f"CRITICAL: Failed during sync connection or table setup: {e}")
112
+
113
 
114
+ # --- Async connect/disconnect functions (remain the same) ---
115
  async def connect_db():
116
  try:
117
  await database.connect()