macrostrat.database 3.3.1__tar.gz → 3.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/PKG-INFO +1 -1
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/mapper/__init__.py +0 -1
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/utils.py +60 -32
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/pyproject.toml +1 -1
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/__init__.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/mapper/base.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/mapper/cache.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/mapper/utils.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/postgresql.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/__init__.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/dump_database.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/move_tables.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/restore_database.py +0 -0
- {macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/utils.py +0 -0
|
@@ -9,6 +9,7 @@ from click import echo, secho
|
|
|
9
9
|
from psycopg2.extensions import set_wait_callback
|
|
10
10
|
from psycopg2.extras import wait_select
|
|
11
11
|
from psycopg2.sql import SQL, Composable, Composed
|
|
12
|
+
import psycopg2.errors
|
|
12
13
|
from rich.console import Console
|
|
13
14
|
from sqlalchemy import MetaData, create_engine, text
|
|
14
15
|
from sqlalchemy.engine import Connection, Engine
|
|
@@ -265,8 +266,28 @@ def _run_sql(connectable, sql, params=None, **kwargs):
|
|
|
265
266
|
if not isinstance(params, list) or not len(params) == len(queries):
|
|
266
267
|
params = [params] * len(queries)
|
|
267
268
|
|
|
268
|
-
for query,
|
|
269
|
-
|
|
269
|
+
for query, _params in zip(queries, params):
|
|
270
|
+
params, pre_bind_params = _split_params(_params)
|
|
271
|
+
|
|
272
|
+
if pre_bind_params is not None:
|
|
273
|
+
if not isinstance(query, SQL):
|
|
274
|
+
query = SQL(query)
|
|
275
|
+
# Pre-bind the parameters using PsycoPG2
|
|
276
|
+
query = query.format(**pre_bind_params)
|
|
277
|
+
|
|
278
|
+
if isinstance(query, (SQL, Composed)):
|
|
279
|
+
query = _render_query(query, connectable)
|
|
280
|
+
|
|
281
|
+
sql_text = str(query)
|
|
282
|
+
if isinstance(query, str):
|
|
283
|
+
sql_text = format(query, strip_comments=True).strip()
|
|
284
|
+
if sql_text == "":
|
|
285
|
+
continue
|
|
286
|
+
# Check for server-bound parameters in sql native style. If there are none, use
|
|
287
|
+
# the SQLAlchemy text() function, otherwise use the raw query string
|
|
288
|
+
if has_server_binds is None:
|
|
289
|
+
has_server_binds = infer_has_server_binds(sql_text)
|
|
290
|
+
|
|
270
291
|
# This only does something for postgresql, but it's harmless to run it for other engines
|
|
271
292
|
set_wait_callback(wait_select)
|
|
272
293
|
|
|
@@ -275,27 +296,6 @@ def _run_sql(connectable, sql, params=None, **kwargs):
|
|
|
275
296
|
except InvalidRequestError:
|
|
276
297
|
trans = None
|
|
277
298
|
try:
|
|
278
|
-
params, pre_bind_params = _split_params(params)
|
|
279
|
-
|
|
280
|
-
if pre_bind_params is not None:
|
|
281
|
-
if not isinstance(query, SQL):
|
|
282
|
-
query = SQL(query)
|
|
283
|
-
# Pre-bind the parameters using PsycoPG2
|
|
284
|
-
query = query.format(**pre_bind_params)
|
|
285
|
-
|
|
286
|
-
if isinstance(query, (SQL, Composed)):
|
|
287
|
-
query = _render_query(query, connectable)
|
|
288
|
-
|
|
289
|
-
sql_text = str(query)
|
|
290
|
-
if isinstance(query, str):
|
|
291
|
-
sql_text = format(query, strip_comments=True).strip()
|
|
292
|
-
if sql_text == "":
|
|
293
|
-
continue
|
|
294
|
-
# Check for server-bound parameters in sql native style. If there are none, use
|
|
295
|
-
# the SQLAlchemy text() function, otherwise use the raw query string
|
|
296
|
-
if has_server_binds is None:
|
|
297
|
-
has_server_binds = infer_has_server_binds(sql_text)
|
|
298
|
-
|
|
299
299
|
log.debug("Executing SQL: \n %s", query)
|
|
300
300
|
if has_server_binds:
|
|
301
301
|
conn = _get_connection(connectable)
|
|
@@ -310,24 +310,52 @@ def _run_sql(connectable, sql, params=None, **kwargs):
|
|
|
310
310
|
elif hasattr(connectable, "commit"):
|
|
311
311
|
connectable.commit()
|
|
312
312
|
pretty_print(sql_text, dim=True)
|
|
313
|
-
except
|
|
314
|
-
_err = str(err.orig).strip()
|
|
315
|
-
dim = "already exists" in _err
|
|
313
|
+
except Exception as err:
|
|
316
314
|
if trans is not None:
|
|
317
315
|
trans.rollback()
|
|
318
316
|
elif hasattr(connectable, "rollback"):
|
|
319
317
|
connectable.rollback()
|
|
320
|
-
|
|
321
|
-
if dim:
|
|
322
|
-
_err = " " + _err
|
|
323
|
-
secho(_err, fg="red", dim=dim)
|
|
324
|
-
log.error(err)
|
|
325
|
-
if raise_errors:
|
|
318
|
+
if raise_errors or _should_raise_query_error(err):
|
|
326
319
|
raise err
|
|
320
|
+
|
|
321
|
+
_print_error(sql_text, err)
|
|
327
322
|
finally:
|
|
328
323
|
set_wait_callback(None)
|
|
329
324
|
|
|
330
325
|
|
|
326
|
+
def _should_raise_query_error(err):
|
|
327
|
+
"""Determine if an error should be raised for a query or not."""
|
|
328
|
+
if not isinstance(err, (ProgrammingError, IntegrityError, InternalError, OperationalError)):
|
|
329
|
+
return True
|
|
330
|
+
|
|
331
|
+
orig_err = getattr(err, "orig", None)
|
|
332
|
+
if orig_err is None:
|
|
333
|
+
return True
|
|
334
|
+
|
|
335
|
+
# If we cancel statements midstream, we should raise the error.
|
|
336
|
+
# We might want to change this behavior in the future, or support more graceful handling of errors from other
|
|
337
|
+
# database backends.
|
|
338
|
+
# Ideally we could handle operational errors more gracefully
|
|
339
|
+
if isinstance(orig_err, psycopg2.errors.QueryCanceled) or getattr(orig_err, "pgcode", None) == "57014":
|
|
340
|
+
return True
|
|
341
|
+
|
|
342
|
+
return False
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _print_error(sql_text, err):
|
|
346
|
+
if orig := getattr(err, "orig", None):
|
|
347
|
+
_err = str(orig)
|
|
348
|
+
else:
|
|
349
|
+
_err = str(err)
|
|
350
|
+
_err = _err.strip()
|
|
351
|
+
dim = "already exists" in _err
|
|
352
|
+
pretty_print(sql_text, fg=None if dim else "red", dim=True)
|
|
353
|
+
if dim:
|
|
354
|
+
_err = " " + _err
|
|
355
|
+
secho(_err, fg="red", dim=dim)
|
|
356
|
+
log.error(err)
|
|
357
|
+
|
|
358
|
+
|
|
331
359
|
def run_sql_file(connectable, filename, params=None, **kwargs):
|
|
332
360
|
return run_sql(connectable, filename, params, interpret_as_file=True, **kwargs)
|
|
333
361
|
|
|
@@ -3,7 +3,7 @@ authors = ["Daven Quinn <dev@davenquinn.com>"]
|
|
|
3
3
|
description = "A SQLAlchemy-based database toolkit."
|
|
4
4
|
name = "macrostrat.database"
|
|
5
5
|
packages = [{ include = "macrostrat" }]
|
|
6
|
-
version = "3.3.
|
|
6
|
+
version = "3.3.3"
|
|
7
7
|
|
|
8
8
|
[tool.poetry.dependencies]
|
|
9
9
|
GeoAlchemy2 = "^0.14.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/move_tables.py
RENAMED
|
File without changes
|
|
File without changes
|
{macrostrat_database-3.3.1 → macrostrat_database-3.3.3}/macrostrat/database/transfer/utils.py
RENAMED
|
File without changes
|