samarth upadhyay commited on
Commit
913a0de
·
verified ·
1 Parent(s): 64a6719

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -44
app.py CHANGED
@@ -11,7 +11,7 @@ from flask_cors import CORS
11
  app = Flask(__name__)
12
  CORS(app)
13
 
14
- # --- STANDARD SAMPLE DATA (Same for everyone) ---
15
  SAMPLE_SQL = """
16
  -- Standard Sample Data
17
  CREATE TABLE Departments (
@@ -31,7 +31,6 @@ CREATE TABLE Employees (
31
  dept_id INT,
32
  role VARCHAR(50),
33
  salary DECIMAL(10, 2)
34
- -- Note: Foreign keys might be loose depending on DB strictness settings
35
  );
36
 
37
  INSERT INTO Employees VALUES (101, 'Alice Smith', 1, 'Engineer', 90000);
@@ -74,7 +73,7 @@ def file_to_sql(file, filename):
74
  else:
75
  df = pd.read_excel(file)
76
 
77
- # 2. Sanitize Table Name (filename without extension, alphanumeric only)
78
  table_name = os.path.splitext(filename)[0]
79
  table_name = "".join([c if c.isalnum() else "_" for c in table_name])
80
  if not table_name: table_name = "uploaded_table"
@@ -100,24 +99,25 @@ def file_to_sql(file, filename):
100
  if pd.isna(v):
101
  vals.append("NULL")
102
  elif isinstance(v, str):
103
- # FIX: Handle nested quotes for Python < 3.12 by extracting variable
104
  clean_v = str(v).replace("'", "''")
105
  vals.append(f"'{clean_v}'")
106
  else:
107
  vals.append(str(v))
108
  inserts.append(f"INSERT INTO {table_name} VALUES ({', '.join(vals)});")
109
 
110
- return create_stmt + "\n".join(inserts) + "\n", table_name
111
 
112
  except Exception as e:
113
- return f"-- Error converting file: {str(e)}\n", None
114
 
115
  @app.route('/api/run-sql', methods=['POST'])
116
  def run_sql():
117
  sql_code = request.form.get('code', '')
118
  db_type = request.form.get('type', 'sqlite').lower()
119
  use_sample = request.form.get('use_sample') == 'true'
120
- uploaded_file = request.files.get('database')
 
 
121
 
122
  if not sql_code:
123
  return jsonify({'output': 'No SQL code provided'}), 400
@@ -126,81 +126,66 @@ def run_sql():
126
  session_id = uuid.uuid4().hex[:8]
127
  temp_file_path = None
128
 
129
- # Prepare Initialization SQL (Sample Data + Uploaded CSV/Excel SQL)
130
  init_sql = ""
131
 
132
  if use_sample:
133
  init_sql += SAMPLE_SQL + "\n"
 
 
 
 
 
 
134
 
135
- if uploaded_file:
136
- fname = uploaded_file.filename.lower()
137
  if fname.endswith('.csv') or fname.endswith('.xlsx') or fname.endswith('.xls'):
138
- # Convert Data file to SQL
139
- converted_sql, table_name = file_to_sql(uploaded_file, uploaded_file.filename)
140
- init_sql += f"-- Imported from {uploaded_file.filename}\n" + converted_sql + "\n"
141
- # Reset uploaded_file because we consumed it; we don't need to pass it as a binary DB
142
- uploaded_file = None
 
 
 
 
 
 
143
 
144
  try:
145
  # --- 1. SQLITE LOGIC ---
146
  if db_type == 'sqlite':
147
  db_target = ":memory:"
148
 
149
- # If user uploaded a binary .db file (and didn't convert it above)
150
- if uploaded_file and (uploaded_file.filename.endswith('.db') or uploaded_file.filename.endswith('.sqlite')):
151
  fd, temp_file_path = tempfile.mkstemp(suffix='.db')
152
  os.close(fd)
153
- uploaded_file.save(temp_file_path)
154
  db_target = temp_file_path
155
 
156
  cmd = ["sqlite3", db_target]
157
  header = ".mode column\n.headers on\n"
158
-
159
- # Combine: Header + Init SQL (Sample/CSV) + User SQL
160
  full_script = header + init_sql + sql_code
161
  output = run_command(cmd, input_text=full_script)
162
 
163
  # --- 2. POSTGRESQL LOGIC ---
164
  elif db_type in ['postgres', 'postgresql']:
165
  schema_name = f"sess_{session_id}"
166
-
167
- # A. Create Schema
168
  run_command(["psql", "-h", "localhost", "-U", "playground", "-d", "playground", "-c", f"CREATE SCHEMA {schema_name};"])
169
-
170
  try:
171
- # B. Handle Binary Dump Upload (if any - distinct from CSV/Excel handled in init_sql)
172
- if uploaded_file: # If it's a .sql dump
173
- dump_content = uploaded_file.read().decode('utf-8', errors='ignore')
174
- init_sql += f"\n{dump_content}\n"
175
-
176
- # C. Run Everything (Init + User Code) inside Schema
177
- # We wrap everything in one transaction block pointing to the schema
178
  full_script = f"SET search_path TO {schema_name};\n{init_sql}\n{sql_code}"
179
-
180
  output = run_command(["psql", "-h", "localhost", "-U", "playground", "-d", "playground"], input_text=full_script)
181
-
182
  finally:
183
  run_command(["psql", "-h", "localhost", "-U", "playground", "-d", "playground", "-c", f"DROP SCHEMA {schema_name} CASCADE;"])
184
 
185
  # --- 3. MYSQL LOGIC ---
186
  elif db_type == 'mysql':
187
  db_name = f"sess_{session_id}"
188
-
189
- # A. Create DB
190
  run_command(["mysql", "-h", "localhost", "-u", "playground", "-e", f"CREATE DATABASE {db_name};"])
191
-
192
  try:
193
- # B. Handle Binary Dump Upload
194
- if uploaded_file:
195
- dump_content = uploaded_file.read().decode('utf-8', errors='ignore')
196
- init_sql += f"\n{dump_content}\n"
197
-
198
- # C. Run Everything
199
- # MySQL accepts multiple statements if we just pipe them
200
  full_script = f"USE {db_name};\n{init_sql}\n{sql_code}"
201
-
202
  output = run_command(["mysql", "-h", "localhost", "-u", "playground", "-t"], input_text=full_script)
203
-
204
  finally:
205
  run_command(["mysql", "-h", "localhost", "-u", "playground", "-e", f"DROP DATABASE {db_name};"])
206
 
 
11
  app = Flask(__name__)
12
  CORS(app)
13
 
14
+ # --- STANDARD SAMPLE DATA ---
15
  SAMPLE_SQL = """
16
  -- Standard Sample Data
17
  CREATE TABLE Departments (
 
31
  dept_id INT,
32
  role VARCHAR(50),
33
  salary DECIMAL(10, 2)
 
34
  );
35
 
36
  INSERT INTO Employees VALUES (101, 'Alice Smith', 1, 'Engineer', 90000);
 
73
  else:
74
  df = pd.read_excel(file)
75
 
76
+ # 2. Sanitize Table Name
77
  table_name = os.path.splitext(filename)[0]
78
  table_name = "".join([c if c.isalnum() else "_" for c in table_name])
79
  if not table_name: table_name = "uploaded_table"
 
99
  if pd.isna(v):
100
  vals.append("NULL")
101
  elif isinstance(v, str):
 
102
  clean_v = str(v).replace("'", "''")
103
  vals.append(f"'{clean_v}'")
104
  else:
105
  vals.append(str(v))
106
  inserts.append(f"INSERT INTO {table_name} VALUES ({', '.join(vals)});")
107
 
108
+ return create_stmt + "\n".join(inserts) + "\n"
109
 
110
  except Exception as e:
111
+ return f"-- Error converting file {filename}: {str(e)}\n"
112
 
113
  @app.route('/api/run-sql', methods=['POST'])
114
  def run_sql():
115
  sql_code = request.form.get('code', '')
116
  db_type = request.form.get('type', 'sqlite').lower()
117
  use_sample = request.form.get('use_sample') == 'true'
118
+
119
+ # SUPPORT MULTIPLE FILES
120
+ uploaded_files = request.files.getlist('database')
121
 
122
  if not sql_code:
123
  return jsonify({'output': 'No SQL code provided'}), 400
 
126
  session_id = uuid.uuid4().hex[:8]
127
  temp_file_path = None
128
 
129
+ # Prepare Initialization SQL
130
  init_sql = ""
131
 
132
  if use_sample:
133
  init_sql += SAMPLE_SQL + "\n"
134
+
135
+ # Process all uploaded files (Convert CSV/Excel to SQL, Append SQL Dumps)
136
+ binary_db_file = None
137
+
138
+ for file in uploaded_files:
139
+ fname = file.filename.lower()
140
 
141
+ # Data Files (CSV/Excel) -> Convert to SQL
 
142
  if fname.endswith('.csv') or fname.endswith('.xlsx') or fname.endswith('.xls'):
143
+ converted_sql = file_to_sql(file, file.filename)
144
+ init_sql += f"-- Imported from {file.filename}\n" + converted_sql + "\n"
145
+
146
+ # SQL Dumps -> Append to Script
147
+ elif fname.endswith('.sql'):
148
+ content = file.read().decode('utf-8', errors='ignore')
149
+ init_sql += f"\n-- Dump from {file.filename}\n{content}\n"
150
+
151
+ # SQLite Binary -> Save for later (Only 1 supported per run for SQLite)
152
+ elif (fname.endswith('.db') or fname.endswith('.sqlite')) and db_type == 'sqlite':
153
+ binary_db_file = file
154
 
155
  try:
156
  # --- 1. SQLITE LOGIC ---
157
  if db_type == 'sqlite':
158
  db_target = ":memory:"
159
 
160
+ # Handle Binary DB File if present
161
+ if binary_db_file:
162
  fd, temp_file_path = tempfile.mkstemp(suffix='.db')
163
  os.close(fd)
164
+ binary_db_file.save(temp_file_path)
165
  db_target = temp_file_path
166
 
167
  cmd = ["sqlite3", db_target]
168
  header = ".mode column\n.headers on\n"
 
 
169
  full_script = header + init_sql + sql_code
170
  output = run_command(cmd, input_text=full_script)
171
 
172
  # --- 2. POSTGRESQL LOGIC ---
173
  elif db_type in ['postgres', 'postgresql']:
174
  schema_name = f"sess_{session_id}"
 
 
175
  run_command(["psql", "-h", "localhost", "-U", "playground", "-d", "playground", "-c", f"CREATE SCHEMA {schema_name};"])
 
176
  try:
 
 
 
 
 
 
 
177
  full_script = f"SET search_path TO {schema_name};\n{init_sql}\n{sql_code}"
 
178
  output = run_command(["psql", "-h", "localhost", "-U", "playground", "-d", "playground"], input_text=full_script)
 
179
  finally:
180
  run_command(["psql", "-h", "localhost", "-U", "playground", "-d", "playground", "-c", f"DROP SCHEMA {schema_name} CASCADE;"])
181
 
182
  # --- 3. MYSQL LOGIC ---
183
  elif db_type == 'mysql':
184
  db_name = f"sess_{session_id}"
 
 
185
  run_command(["mysql", "-h", "localhost", "-u", "playground", "-e", f"CREATE DATABASE {db_name};"])
 
186
  try:
 
 
 
 
 
 
 
187
  full_script = f"USE {db_name};\n{init_sql}\n{sql_code}"
 
188
  output = run_command(["mysql", "-h", "localhost", "-u", "playground", "-t"], input_text=full_script)
 
189
  finally:
190
  run_command(["mysql", "-h", "localhost", "-u", "playground", "-e", f"DROP DATABASE {db_name};"])
191