Seth commited on
Commit
1b782b4
·
1 Parent(s): 50e855b
Files changed (1) hide show
  1. backend/app/database.py +104 -75
backend/app/database.py CHANGED
@@ -12,15 +12,16 @@ except ImportError:
12
 
13
  # Get database URL from environment variable
14
  # Default to SQLite for local development if not set
15
- DATABASE_URL = os.getenv(
16
  "DATABASE_URL",
17
  "sqlite:///./postgen.db"
18
  )
 
19
 
20
  # For CockroachDB, we need to handle SSL and connection pooling
21
- if DATABASE_URL.startswith("postgresql://") or DATABASE_URL.startswith("postgres://"):
22
- # Check if this is a CockroachDB connection
23
- is_cockroach = "cockroachlabs" in DATABASE_URL.lower()
24
 
25
  # CockroachDB connection - use NullPool to avoid connection issues
26
  # CockroachDB requires SSL, so we ensure sslmode is set
@@ -86,78 +87,106 @@ def init_db():
86
  # Check if it's a version parsing error (non-fatal for CockroachDB)
87
  if "Could not determine version" in error_str:
88
  # Version parsing failed, but CockroachDB connection works
89
- # Try to create tables using raw SQL to bypass version check
90
  try:
91
- # Use raw connection to create tables
92
- with engine.raw_connection() as raw_conn:
93
- cursor = raw_conn.cursor()
94
- # Create tables using IF NOT EXISTS
95
- tables_sql = [
96
- """CREATE TABLE IF NOT EXISTS users (
97
- id SERIAL PRIMARY KEY,
98
- email VARCHAR UNIQUE,
99
- name VARCHAR,
100
- created_at TIMESTAMP DEFAULT NOW()
101
- )""",
102
- """CREATE TABLE IF NOT EXISTS integrations (
103
- id SERIAL PRIMARY KEY,
104
- user_id INTEGER REFERENCES users(id),
105
- provider VARCHAR,
106
- access_token TEXT,
107
- refresh_token TEXT,
108
- expires_at TIMESTAMP,
109
- account_info JSONB,
110
- connected BOOLEAN DEFAULT FALSE,
111
- created_at TIMESTAMP DEFAULT NOW(),
112
- updated_at TIMESTAMP DEFAULT NOW()
113
- )""",
114
- """CREATE TABLE IF NOT EXISTS assets (
115
- id SERIAL PRIMARY KEY,
116
- user_id INTEGER REFERENCES users(id),
117
- name VARCHAR,
118
- file_path VARCHAR,
119
- file_type VARCHAR,
120
- product_category VARCHAR,
121
- sub_category VARCHAR,
122
- size INTEGER,
123
- extra_metadata JSONB,
124
- created_at TIMESTAMP DEFAULT NOW()
125
- )""",
126
- """CREATE TABLE IF NOT EXISTS posts (
127
- id SERIAL PRIMARY KEY,
128
- user_id INTEGER REFERENCES users(id),
129
- title VARCHAR,
130
- content TEXT,
131
- post_type VARCHAR,
132
- product_category VARCHAR,
133
- scheduled_date TIMESTAMP,
134
- status VARCHAR,
135
- linkedin_post_id VARCHAR,
136
- canva_design_id VARCHAR,
137
- assets JSONB,
138
- extra_metadata JSONB,
139
- created_at TIMESTAMP DEFAULT NOW(),
140
- updated_at TIMESTAMP DEFAULT NOW()
141
- )""",
142
- """CREATE TABLE IF NOT EXISTS campaigns (
143
- id SERIAL PRIMARY KEY,
144
- user_id INTEGER REFERENCES users(id),
145
- name VARCHAR,
146
- date_range_start TIMESTAMP,
147
- date_range_end TIMESTAMP,
148
- products JSONB,
149
- post_types JSONB,
150
- posts_per_week INTEGER,
151
- status VARCHAR,
152
- created_at TIMESTAMP DEFAULT NOW(),
153
- updated_at TIMESTAMP DEFAULT NOW()
154
- )"""
155
- ]
156
- for sql in tables_sql:
157
- cursor.execute(sql)
158
- raw_conn.commit()
159
- cursor.close()
160
- print("✓ CockroachDB tables created successfully (using raw SQL)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  return True
162
  except Exception as raw_error:
163
  print(f"⚠ Table creation failed: {raw_error}")
 
12
 
13
  # Get database URL from environment variable
14
  # Default to SQLite for local development if not set
15
+ ORIGINAL_DATABASE_URL = os.getenv(
16
  "DATABASE_URL",
17
  "sqlite:///./postgen.db"
18
  )
19
+ DATABASE_URL = ORIGINAL_DATABASE_URL
20
 
21
  # For CockroachDB, we need to handle SSL and connection pooling
22
+ if ORIGINAL_DATABASE_URL.startswith("postgresql://") or ORIGINAL_DATABASE_URL.startswith("postgres://") or ORIGINAL_DATABASE_URL.startswith("cockroachdb://"):
23
+ # Check if this is a CockroachDB connection (use original URL before modifications)
24
+ is_cockroach = "cockroachlabs" in ORIGINAL_DATABASE_URL.lower()
25
 
26
  # CockroachDB connection - use NullPool to avoid connection issues
27
  # CockroachDB requires SSL, so we ensure sslmode is set
 
87
  # Check if it's a version parsing error (non-fatal for CockroachDB)
88
  if "Could not determine version" in error_str:
89
  # Version parsing failed, but CockroachDB connection works
90
+ # Use psycopg2 directly to bypass SQLAlchemy's version parsing
91
  try:
92
+ import psycopg2
93
+ from urllib.parse import urlparse, parse_qs
94
+
95
+ # Parse connection string to get connection parameters
96
+ # Handle both cockroachdb:// and postgresql:// schemes
97
+ # Use original URL before any modifications
98
+ url_for_parsing = ORIGINAL_DATABASE_URL.replace("cockroachdb://", "postgresql://")
99
+ parsed = urlparse(url_for_parsing)
100
+ dbname = parsed.path[1:] if parsed.path else "defaultdb"
101
+ user = parsed.username
102
+ password = parsed.password
103
+ host = parsed.hostname
104
+ port = parsed.port or 26257
105
+
106
+ # Get sslmode from query params (use require as default for CockroachDB)
107
+ params = parse_qs(parsed.query)
108
+ sslmode_list = params.get('sslmode', ['require'])
109
+ sslmode = sslmode_list[0] if sslmode_list else 'require'
110
+
111
+ # Connect directly with psycopg2 (bypasses SQLAlchemy version parsing)
112
+ conn = psycopg2.connect(
113
+ dbname=dbname,
114
+ user=user,
115
+ password=password,
116
+ host=host,
117
+ port=port,
118
+ sslmode=sslmode
119
+ )
120
+
121
+ cursor = conn.cursor()
122
+ # Create tables using IF NOT EXISTS
123
+ tables_sql = [
124
+ """CREATE TABLE IF NOT EXISTS users (
125
+ id SERIAL PRIMARY KEY,
126
+ email VARCHAR UNIQUE,
127
+ name VARCHAR,
128
+ created_at TIMESTAMP DEFAULT NOW()
129
+ )""",
130
+ """CREATE TABLE IF NOT EXISTS integrations (
131
+ id SERIAL PRIMARY KEY,
132
+ user_id INTEGER REFERENCES users(id),
133
+ provider VARCHAR,
134
+ access_token TEXT,
135
+ refresh_token TEXT,
136
+ expires_at TIMESTAMP,
137
+ account_info JSONB,
138
+ connected BOOLEAN DEFAULT FALSE,
139
+ created_at TIMESTAMP DEFAULT NOW(),
140
+ updated_at TIMESTAMP DEFAULT NOW()
141
+ )""",
142
+ """CREATE TABLE IF NOT EXISTS assets (
143
+ id SERIAL PRIMARY KEY,
144
+ user_id INTEGER REFERENCES users(id),
145
+ name VARCHAR,
146
+ file_path VARCHAR,
147
+ file_type VARCHAR,
148
+ product_category VARCHAR,
149
+ sub_category VARCHAR,
150
+ size INTEGER,
151
+ extra_metadata JSONB,
152
+ created_at TIMESTAMP DEFAULT NOW()
153
+ )""",
154
+ """CREATE TABLE IF NOT EXISTS posts (
155
+ id SERIAL PRIMARY KEY,
156
+ user_id INTEGER REFERENCES users(id),
157
+ title VARCHAR,
158
+ content TEXT,
159
+ post_type VARCHAR,
160
+ product_category VARCHAR,
161
+ scheduled_date TIMESTAMP,
162
+ status VARCHAR,
163
+ linkedin_post_id VARCHAR,
164
+ canva_design_id VARCHAR,
165
+ assets JSONB,
166
+ extra_metadata JSONB,
167
+ created_at TIMESTAMP DEFAULT NOW(),
168
+ updated_at TIMESTAMP DEFAULT NOW()
169
+ )""",
170
+ """CREATE TABLE IF NOT EXISTS campaigns (
171
+ id SERIAL PRIMARY KEY,
172
+ user_id INTEGER REFERENCES users(id),
173
+ name VARCHAR,
174
+ date_range_start TIMESTAMP,
175
+ date_range_end TIMESTAMP,
176
+ products JSONB,
177
+ post_types JSONB,
178
+ posts_per_week INTEGER,
179
+ status VARCHAR,
180
+ created_at TIMESTAMP DEFAULT NOW(),
181
+ updated_at TIMESTAMP DEFAULT NOW()
182
+ )"""
183
+ ]
184
+ for sql in tables_sql:
185
+ cursor.execute(sql)
186
+ conn.commit()
187
+ cursor.close()
188
+ conn.close()
189
+ print("✓ CockroachDB tables created successfully (using direct psycopg2 connection)")
190
  return True
191
  except Exception as raw_error:
192
  print(f"⚠ Table creation failed: {raw_error}")