stvnnnnnn commited on
Commit
e10bdac
·
verified ·
1 Parent(s): 9187593

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -27
app.py CHANGED
@@ -161,6 +161,7 @@ class PostgresManager:
161
  para hacer SELECT sobre las tablas).
162
  - Ignoramos errores tipo “already exists” para que no reviente si
163
  el script crea dos veces la misma tabla/índice.
 
164
  """
165
  connection_id = self._new_connection_id()
166
  schema_name = f"sess_{uuid.uuid4().hex[:8]}"
@@ -184,13 +185,16 @@ class PostgresManager:
184
  copy_sql = ""
185
  copy_rows: list[str] = []
186
 
187
- in_function = False # estamos dentro de un CREATE FUNCTION ... $$ ... $$
188
- function_end_delim: str | None = None
 
 
189
 
190
  stmt_lines: list[str] = []
191
 
192
  def flush_statement():
193
  """Ejecuta el statement acumulado si es útil."""
 
194
  stmt = "\n".join(stmt_lines).strip()
195
  stmt_lines.clear()
196
  if not stmt or stmt == ";":
@@ -198,7 +202,7 @@ class PostgresManager:
198
 
199
  upper = stmt.upper()
200
 
201
- # 1) Saltar cosas peligrosas o globales
202
  skip_prefixes = (
203
  "SET ",
204
  "SELECT PG_CATALOG.SET_CONFIG",
@@ -215,19 +219,11 @@ class PostgresManager:
215
  if upper.startswith(skip_prefixes):
216
  return
217
 
218
- # 2) Saltar cualquier sentencia que intente cambiar OWNER o ROLES
219
- # Ejemplos:
220
- # ALTER TABLE ... OWNER TO postgres;
221
- # ALTER FUNCTION ... OWNER TO postgres;
222
- # CREATE ROLE postgres;
223
- # ALTER ROLE postgres ...;
224
- # SET ROLE postgres;
225
  if " OWNER TO " in upper:
226
  return
227
- if upper.startswith("CREATE ROLE") or upper.startswith("ALTER ROLE") or upper.startswith("SET ROLE"):
228
- return
229
 
230
- # 3) Quitar ';' final (psycopg2 no la necesita)
231
  if stmt.endswith(";"):
232
  stmt = stmt[:-1]
233
 
@@ -235,7 +231,7 @@ class PostgresManager:
235
  cur.execute(stmt)
236
  except Exception as e:
237
  msg = str(e).lower()
238
- # Ignorar errores típicos de dumps (idempotencia)
239
  if "already exists" in msg or "duplicate key value" in msg:
240
  print("[WARN] Ignorando error no crítico:", e)
241
  return
@@ -245,7 +241,7 @@ class PostgresManager:
245
  line = raw_line.rstrip("\n")
246
  stripped = line.strip()
247
 
248
- # Comentarios o líneas vacías
249
  if not in_copy and not in_function:
250
  if not stripped or stripped.startswith("--"):
251
  continue
@@ -261,9 +257,23 @@ class PostgresManager:
261
  copy_rows.append(line)
262
  continue
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  if (
265
  stripped.upper().startswith("COPY ")
266
- and "FROM stdin" in stripped
267
  ):
268
  flush_statement()
269
  in_copy = True
@@ -271,25 +281,30 @@ class PostgresManager:
271
  copy_rows = []
272
  continue
273
 
274
- # ====== BLOQUE CREATE FUNCTION ... $$ ... $$ ======
275
- if in_function:
276
- # seguimos saltando hasta encontrar el delimitador de cierre
277
- if function_end_delim and function_end_delim in stripped:
278
- in_function = False
279
- function_end_delim = None
280
- continue
281
-
282
  if stripped.upper().startswith("CREATE FUNCTION") or stripped.upper().startswith(
283
  "CREATE OR REPLACE FUNCTION"
284
  ):
285
  # Entramos en bloque función → lo ignoramos entero
286
  in_function = True
287
- # detectar el delimitador $$...$$ por si viene con nombre ($body$ etc)
 
288
  m = re.search(r"\$(\w*)\$", stripped)
289
  if m:
290
- function_end_delim = f"${m.group(1)}$"
291
  else:
292
- function_end_delim = "$$"
 
 
 
 
 
 
 
 
 
 
 
293
  continue
294
 
295
  # ====== STATEMENTS NORMALES ======
 
161
  para hacer SELECT sobre las tablas).
162
  - Ignoramos errores tipo “already exists” para que no reviente si
163
  el script crea dos veces la misma tabla/índice.
164
+ - Ignoramos sentencias que cambian OWNER a 'postgres'.
165
  """
166
  connection_id = self._new_connection_id()
167
  schema_name = f"sess_{uuid.uuid4().hex[:8]}"
 
185
  copy_sql = ""
186
  copy_rows: list[str] = []
187
 
188
+ # NUEVO: estado para funciones
189
+ in_function = False
190
+ function_delim: str | None = None
191
+ function_delim_count: int = 0
192
 
193
  stmt_lines: list[str] = []
194
 
195
  def flush_statement():
196
  """Ejecuta el statement acumulado si es útil."""
197
+ nonlocal stmt_lines
198
  stmt = "\n".join(stmt_lines).strip()
199
  stmt_lines.clear()
200
  if not stmt or stmt == ";":
 
202
 
203
  upper = stmt.upper()
204
 
205
+ # Saltar cosas globales/peligrosas
206
  skip_prefixes = (
207
  "SET ",
208
  "SELECT PG_CATALOG.SET_CONFIG",
 
219
  if upper.startswith(skip_prefixes):
220
  return
221
 
222
+ # Saltar ALTER ... OWNER TO postgres (u otros OWNER)
 
 
 
 
 
 
223
  if " OWNER TO " in upper:
224
  return
 
 
225
 
226
+ # Quitar ';' final (psycopg2 no la necesita)
227
  if stmt.endswith(";"):
228
  stmt = stmt[:-1]
229
 
 
231
  cur.execute(stmt)
232
  except Exception as e:
233
  msg = str(e).lower()
234
+ # Ignorar cosas no fatales típicas de dumps
235
  if "already exists" in msg or "duplicate key value" in msg:
236
  print("[WARN] Ignorando error no crítico:", e)
237
  return
 
241
  line = raw_line.rstrip("\n")
242
  stripped = line.strip()
243
 
244
+ # Comentarios o líneas vacías (si no estamos en COPY/función)
245
  if not in_copy and not in_function:
246
  if not stripped or stripped.startswith("--"):
247
  continue
 
257
  copy_rows.append(line)
258
  continue
259
 
260
+ # ====== BLOQUE CREATE FUNCTION ... $$ ... $$ (IGNORAR) ======
261
+ if in_function:
262
+ # Contamos apariciones del delimitador ($$ o $body$)
263
+ if function_delim:
264
+ function_delim_count += line.count(function_delim)
265
+ # Cuando lo hemos visto al menos 2 veces
266
+ # (apertura y cierre) salimos del bloque función
267
+ if function_delim_count >= 2:
268
+ in_function = False
269
+ function_delim = None
270
+ function_delim_count = 0
271
+ continue
272
+
273
+ # Detectar inicio de COPY
274
  if (
275
  stripped.upper().startswith("COPY ")
276
+ and "FROM stdin" in stripped.upper()
277
  ):
278
  flush_statement()
279
  in_copy = True
 
281
  copy_rows = []
282
  continue
283
 
284
+ # Detectar inicio de función: CREATE [OR REPLACE] FUNCTION ...
 
 
 
 
 
 
 
285
  if stripped.upper().startswith("CREATE FUNCTION") or stripped.upper().startswith(
286
  "CREATE OR REPLACE FUNCTION"
287
  ):
288
  # Entramos en bloque función → lo ignoramos entero
289
  in_function = True
290
+
291
+ # Detectar delimitador tipo $$ o $algo$
292
  m = re.search(r"\$(\w*)\$", stripped)
293
  if m:
294
+ function_delim = f"${m.group(1)}$"
295
  else:
296
+ function_delim = "$$"
297
+
298
+ # Contamos cuántas veces aparece ya en esta línea
299
+ function_delim_count = stripped.count(function_delim)
300
+
301
+ # Caso raro: función toda en una sola línea (apertura+cierre)
302
+ if function_delim_count >= 2:
303
+ in_function = False
304
+ function_delim = None
305
+ function_delim_count = 0
306
+
307
+ # No añadimos la línea al buffer, se ignora
308
  continue
309
 
310
  # ====== STATEMENTS NORMALES ======