Spaces:
Running
Running
Upload 10 files
Browse files
main.py
CHANGED
@@ -271,52 +271,91 @@ async def startup_db_client():
|
|
271 |
raise Exception(error_msg)
|
272 |
|
273 |
# Create tables if they don't exist
|
274 |
-
try
|
275 |
-
|
276 |
|
277 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
CREATE TABLE IF NOT EXISTS users (
|
279 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
280 |
-
email TEXT NOT NULL UNIQUE
|
281 |
-
hashed_password TEXT NOT NULL
|
282 |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
283 |
last_login DATETIME,
|
284 |
-
is_admin
|
285 |
)
|
286 |
-
"""
|
|
|
|
|
287 |
|
288 |
-
|
|
|
289 |
CREATE TABLE IF NOT EXISTS projects (
|
290 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
291 |
owner_id INTEGER NOT NULL,
|
292 |
-
title TEXT NOT NULL
|
293 |
-
description TEXT
|
294 |
geojson TEXT,
|
295 |
storage_bucket TEXT DEFAULT 'default',
|
296 |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
297 |
-
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
298 |
-
FOREIGN KEY (owner_id) REFERENCES users(id)
|
299 |
)
|
300 |
-
"""
|
|
|
|
|
301 |
|
302 |
-
|
|
|
303 |
CREATE TABLE IF NOT EXISTS journals (
|
304 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
305 |
project_id INTEGER NOT NULL,
|
306 |
-
title TEXT NOT NULL
|
307 |
-
content TEXT
|
308 |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
309 |
-
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
310 |
-
FOREIGN KEY (project_id) REFERENCES projects(id)
|
311 |
)
|
312 |
-
"""
|
|
|
|
|
313 |
|
314 |
-
|
315 |
-
logger.info("Database tables created successfully")
|
316 |
except Exception as e:
|
317 |
error_msg = f"Failed to create database tables: {str(e)}"
|
318 |
logger.error(error_msg)
|
319 |
-
|
|
|
|
|
320 |
|
321 |
@app.on_event("shutdown")
|
322 |
async def shutdown_db_client():
|
|
|
271 |
raise Exception(error_msg)
|
272 |
|
273 |
# Create tables if they don't exist
|
274 |
+
# We'll create each table in a separate try-except block to ensure that if one fails, others can still be created
|
275 |
+
logger.info("Creating database tables")
|
276 |
|
277 |
+
# Function to execute SQL with retry
|
278 |
+
def execute_with_retry(sql, max_retries=3):
|
279 |
+
for attempt in range(max_retries):
|
280 |
+
try:
|
281 |
+
# For each attempt, we'll create a fresh connection if needed
|
282 |
+
if attempt > 0:
|
283 |
+
logger.info(f"Retry attempt {attempt+1} for SQL execution")
|
284 |
+
# Test the connection first
|
285 |
+
try:
|
286 |
+
test_result = app.db_conn.execute("SELECT 1").fetchone()
|
287 |
+
logger.info(f"Connection test successful: {test_result}")
|
288 |
+
except Exception as conn_err:
|
289 |
+
logger.warning(f"Connection test failed, reconnecting: {str(conn_err)}")
|
290 |
+
# Reconnect using the same method that worked initially
|
291 |
+
if app.db_type == "libsql-experimental":
|
292 |
+
app.db_conn = libsql.connect(db_url, auth_token=clean_auth_token)
|
293 |
+
|
294 |
+
# Execute the SQL
|
295 |
+
app.db_conn.execute(sql)
|
296 |
+
app.db_conn.commit()
|
297 |
+
return True
|
298 |
+
except Exception as e:
|
299 |
+
logger.warning(f"SQL execution failed (attempt {attempt+1}): {str(e)}")
|
300 |
+
if attempt == max_retries - 1:
|
301 |
+
raise
|
302 |
+
# Small delay before retry
|
303 |
+
import time
|
304 |
+
time.sleep(1)
|
305 |
+
|
306 |
+
# Simplified table creation with fewer constraints
|
307 |
+
try:
|
308 |
+
# Create users table
|
309 |
+
users_table = """
|
310 |
CREATE TABLE IF NOT EXISTS users (
|
311 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
312 |
+
email TEXT NOT NULL UNIQUE,
|
313 |
+
hashed_password TEXT NOT NULL,
|
314 |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
315 |
last_login DATETIME,
|
316 |
+
is_admin INTEGER DEFAULT 0
|
317 |
)
|
318 |
+
"""
|
319 |
+
execute_with_retry(users_table)
|
320 |
+
logger.info("Users table created successfully")
|
321 |
|
322 |
+
# Create projects table
|
323 |
+
projects_table = """
|
324 |
CREATE TABLE IF NOT EXISTS projects (
|
325 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
326 |
owner_id INTEGER NOT NULL,
|
327 |
+
title TEXT NOT NULL,
|
328 |
+
description TEXT,
|
329 |
geojson TEXT,
|
330 |
storage_bucket TEXT DEFAULT 'default',
|
331 |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
332 |
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
|
333 |
)
|
334 |
+
"""
|
335 |
+
execute_with_retry(projects_table)
|
336 |
+
logger.info("Projects table created successfully")
|
337 |
|
338 |
+
# Create journals table
|
339 |
+
journals_table = """
|
340 |
CREATE TABLE IF NOT EXISTS journals (
|
341 |
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
342 |
project_id INTEGER NOT NULL,
|
343 |
+
title TEXT NOT NULL,
|
344 |
+
content TEXT,
|
345 |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
346 |
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
|
347 |
)
|
348 |
+
"""
|
349 |
+
execute_with_retry(journals_table)
|
350 |
+
logger.info("Journals table created successfully")
|
351 |
|
352 |
+
logger.info("All database tables created successfully")
|
|
|
353 |
except Exception as e:
|
354 |
error_msg = f"Failed to create database tables: {str(e)}"
|
355 |
logger.error(error_msg)
|
356 |
+
# We'll continue even if table creation fails
|
357 |
+
# This allows the server to start and use existing tables if they exist
|
358 |
+
logger.warning("Continuing server startup despite table creation errors")
|
359 |
|
360 |
@app.on_event("shutdown")
|
361 |
async def shutdown_db_client():
|