Seth commited on
Commit
df2dd5d
·
1 Parent(s): bc701fb
Files changed (2) hide show
  1. backend/app/database.py +40 -0
  2. backend/app/main.py +97 -63
backend/app/database.py CHANGED
@@ -71,6 +71,46 @@ def get_db():
71
  finally:
72
  db.close()
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  def init_db():
75
  """Initialize database tables"""
76
  try:
 
71
  finally:
72
  db.close()
73
 
74
+ def get_direct_psycopg2_connection():
75
+ """Get a direct psycopg2 connection bypassing SQLAlchemy version parsing"""
76
+ try:
77
+ import psycopg2
78
+ from urllib.parse import urlparse, parse_qs
79
+
80
+ # Only for PostgreSQL/CockroachDB connections
81
+ if not (ORIGINAL_DATABASE_URL.startswith("postgresql://") or
82
+ ORIGINAL_DATABASE_URL.startswith("postgres://") or
83
+ ORIGINAL_DATABASE_URL.startswith("cockroachdb://")):
84
+ return None
85
+
86
+ # Parse connection string
87
+ url_for_parsing = ORIGINAL_DATABASE_URL.replace("cockroachdb://", "postgresql://")
88
+ parsed = urlparse(url_for_parsing)
89
+ dbname = parsed.path[1:] if parsed.path else "defaultdb"
90
+ user = parsed.username
91
+ password = parsed.password
92
+ host = parsed.hostname
93
+ port = parsed.port or 26257
94
+
95
+ # Get sslmode from query params
96
+ params = parse_qs(parsed.query)
97
+ sslmode_list = params.get('sslmode', ['require'])
98
+ sslmode = sslmode_list[0] if sslmode_list else 'require'
99
+
100
+ # Create connection
101
+ conn = psycopg2.connect(
102
+ dbname=dbname,
103
+ user=user,
104
+ password=password,
105
+ host=host,
106
+ port=port,
107
+ sslmode=sslmode
108
+ )
109
+ return conn
110
+ except Exception as e:
111
+ print(f"Failed to create direct psycopg2 connection: {e}")
112
+ return None
113
+
114
  def init_db():
115
  """Initialize database tables"""
116
  try:
backend/app/main.py CHANGED
@@ -16,7 +16,7 @@ from app.schemas import (
16
  from app.services.canva_service import CanvaService
17
  from app.services.linkedin_service import LinkedInService
18
  from app.services.ai_service import AIService
19
- from app.database import init_db, get_db
20
  from sqlalchemy.orm import Session
21
 
22
  app = FastAPI(title="PostGen API", version="1.0.0")
@@ -205,50 +205,65 @@ async def upload_asset(
205
  # Refresh might fail due to version string, but commit succeeded
206
  # Query the asset back to get the ID
207
  if "Could not determine version" in str(refresh_error):
208
- from sqlalchemy import text
209
- result = db.execute(
210
- text("SELECT id, created_at FROM assets WHERE name = :name AND file_path = :file_path ORDER BY id DESC LIMIT 1"),
211
- {"name": file.filename, "file_path": str(file_path)}
212
- )
213
- row = result.fetchone()
214
- if row:
215
- db_asset.id = row[0]
216
- # Set created_at if available
217
- if hasattr(db_asset, 'created_at') and row[1]:
218
- db_asset.created_at = row[1]
 
 
 
 
 
 
 
 
 
 
219
  else:
220
  raise refresh_error
221
  except Exception as commit_error:
222
- # If commit fails due to version string issue, try raw SQL
223
  db.rollback()
224
  error_str = str(commit_error)
225
  if "Could not determine version" in error_str:
226
- # Try using raw SQL to insert
227
- from sqlalchemy import text
228
- try:
229
- result = db.execute(
230
- text("""
 
231
  INSERT INTO assets (name, file_path, file_type, product_category, sub_category, size, user_id, created_at)
232
- VALUES (:name, :file_path, :file_type, :product_category, :sub_category, :size, :user_id, NOW())
233
  RETURNING id, created_at
234
- """),
235
- {
236
- "name": file.filename,
237
- "file_path": str(file_path),
238
- "file_type": file_type,
239
- "product_category": product_category or "ocr",
240
- "sub_category": sub_category if sub_category and sub_category != "none" else None,
241
- "size": file_size,
242
- "user_id": 1
243
- }
244
- )
245
- row = result.fetchone()
246
- if row:
247
- db_asset.id = row[0]
248
- db_asset.created_at = row[1]
249
- db.commit()
250
- except Exception as sql_error:
251
- print(f"Raw SQL insert also failed: {sql_error}")
 
 
 
 
252
  raise commit_error
253
  else:
254
  raise commit_error
@@ -310,32 +325,51 @@ async def get_assets(
310
  "created_at": asset.created_at
311
  })
312
  except Exception as orm_error:
313
- # If ORM fails due to version string issue, use raw SQL
314
- print(f"ORM query warning, using raw SQL: {orm_error}")
315
- try:
316
- sql_query = "SELECT id, name, file_path, file_type, product_category, sub_category, size, created_at FROM assets"
317
- params = {}
318
- if product_category and product_category != "all":
319
- sql_query += " WHERE product_category = :product_category"
320
- params["product_category"] = product_category
321
- sql_query += " ORDER BY created_at DESC"
322
-
323
- result = db.execute(text(sql_query), params)
324
- rows = result.fetchall()
325
-
326
- assets = []
327
- for row in rows:
328
- assets.append({
329
- "id": row[0],
330
- "name": row[1],
331
- "file_type": row[3],
332
- "product_category": row[4],
333
- "sub_category": row[5],
334
- "size": row[6],
335
- "created_at": row[7]
336
- })
337
- except Exception as sql_error:
338
- print(f"Raw SQL query also failed: {sql_error}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  assets = []
340
 
341
  # Merge with mock data (as requested - keep dummy content)
 
16
  from app.services.canva_service import CanvaService
17
  from app.services.linkedin_service import LinkedInService
18
  from app.services.ai_service import AIService
19
+ from app.database import init_db, get_db, get_direct_psycopg2_connection
20
  from sqlalchemy.orm import Session
21
 
22
  app = FastAPI(title="PostGen API", version="1.0.0")
 
205
  # Refresh might fail due to version string, but commit succeeded
206
  # Query the asset back to get the ID
207
  if "Could not determine version" in str(refresh_error):
208
+ # Use direct psycopg2 to query back the asset
209
+ conn = get_direct_psycopg2_connection()
210
+ if conn:
211
+ try:
212
+ cursor = conn.cursor()
213
+ cursor.execute("""
214
+ SELECT id, created_at FROM assets
215
+ WHERE name = %s AND file_path = %s
216
+ ORDER BY id DESC LIMIT 1
217
+ """, (file.filename, str(file_path)))
218
+ row = cursor.fetchone()
219
+ cursor.close()
220
+ conn.close()
221
+ if row:
222
+ db_asset.id = row[0]
223
+ if hasattr(db_asset, 'created_at') and row[1]:
224
+ db_asset.created_at = row[1]
225
+ except Exception as psycopg2_error:
226
+ print(f"Direct psycopg2 query failed: {psycopg2_error}")
227
+ if conn:
228
+ conn.close()
229
  else:
230
  raise refresh_error
231
  except Exception as commit_error:
232
+ # If commit fails due to version string issue, use direct psycopg2
233
  db.rollback()
234
  error_str = str(commit_error)
235
  if "Could not determine version" in error_str:
236
+ # Use direct psycopg2 connection to bypass SQLAlchemy
237
+ conn = get_direct_psycopg2_connection()
238
+ if conn:
239
+ try:
240
+ cursor = conn.cursor()
241
+ cursor.execute("""
242
  INSERT INTO assets (name, file_path, file_type, product_category, sub_category, size, user_id, created_at)
243
+ VALUES (%s, %s, %s, %s, %s, %s, %s, NOW())
244
  RETURNING id, created_at
245
+ """, (
246
+ file.filename,
247
+ str(file_path),
248
+ file_type,
249
+ product_category or "ocr",
250
+ sub_category if sub_category and sub_category != "none" else None,
251
+ file_size,
252
+ 1
253
+ ))
254
+ row = cursor.fetchone()
255
+ conn.commit()
256
+ cursor.close()
257
+ conn.close()
258
+ if row:
259
+ db_asset.id = row[0]
260
+ db_asset.created_at = row[1]
261
+ except Exception as psycopg2_error:
262
+ print(f"Direct psycopg2 insert failed: {psycopg2_error}")
263
+ if conn:
264
+ conn.close()
265
+ raise commit_error
266
+ else:
267
  raise commit_error
268
  else:
269
  raise commit_error
 
325
  "created_at": asset.created_at
326
  })
327
  except Exception as orm_error:
328
+ # If ORM fails due to version string issue, use direct psycopg2
329
+ error_str = str(orm_error)
330
+ if "Could not determine version" in error_str:
331
+ # Use direct psycopg2 connection to bypass SQLAlchemy
332
+ conn = get_direct_psycopg2_connection()
333
+ if conn:
334
+ try:
335
+ cursor = conn.cursor()
336
+ if product_category and product_category != "all":
337
+ cursor.execute("""
338
+ SELECT id, name, file_path, file_type, product_category, sub_category, size, created_at
339
+ FROM assets
340
+ WHERE product_category = %s
341
+ ORDER BY created_at DESC
342
+ """, (product_category,))
343
+ else:
344
+ cursor.execute("""
345
+ SELECT id, name, file_path, file_type, product_category, sub_category, size, created_at
346
+ FROM assets
347
+ ORDER BY created_at DESC
348
+ """)
349
+ rows = cursor.fetchall()
350
+ cursor.close()
351
+ conn.close()
352
+
353
+ assets = []
354
+ for row in rows:
355
+ assets.append({
356
+ "id": row[0],
357
+ "name": row[1],
358
+ "file_type": row[3],
359
+ "product_category": row[4],
360
+ "sub_category": row[5],
361
+ "size": row[6],
362
+ "created_at": row[7]
363
+ })
364
+ except Exception as psycopg2_error:
365
+ print(f"Direct psycopg2 query failed: {psycopg2_error}")
366
+ if conn:
367
+ conn.close()
368
+ assets = []
369
+ else:
370
+ assets = []
371
+ else:
372
+ print(f"ORM query error: {orm_error}")
373
  assets = []
374
 
375
  # Merge with mock data (as requested - keep dummy content)