mtpk-postgres 0.1.3__tar.gz → 0.1.4__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.
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/PKG-INFO +13 -1
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/README.md +12 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres/__init__.py +1 -1
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres/core_sync.py +39 -5
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres.egg-info/PKG-INFO +13 -1
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/pyproject.toml +1 -1
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/LICENSE +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres/async_adapter.py +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres/crud.py +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres/excepciones.py +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres/interface.py +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres/utils.py +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres.egg-info/SOURCES.txt +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres.egg-info/dependency_links.txt +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres.egg-info/requires.txt +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/mtpk_postgres.egg-info/top_level.txt +0 -0
- {mtpk_postgres-0.1.3 → mtpk_postgres-0.1.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mtpk_postgres
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Librería para sincronización estructural de bases de datos Postgres con modelos Python (adaptación de mtpk_mariadb)
|
|
5
5
|
Author-email: José Jesús Andrés Zambrana <jjandres@multiplika.es>
|
|
6
6
|
License: MIT
|
|
@@ -54,6 +54,18 @@ pip install -e .
|
|
|
54
54
|
|
|
55
55
|
## Historial
|
|
56
56
|
|
|
57
|
+
- **0.1.4**: corrige la causa de fondo del bug de la 0.1.3, que solo tapaba el síntoma en la columna generada
|
|
58
|
+
en sí. Había dos problemas relacionados: (1) `comparar_generar_alter` comparaba el tipo de columna por su
|
|
59
|
+
nombre "en crudo" (`col.tipo`), así que un modelo que usa alias como `INT`, `TINYINT` o `DATETIME` (en vez de
|
|
60
|
+
`INTEGER`/`SMALLINT`/`TIMESTAMP`, que es como se reconstruyen siempre desde Postgres) nunca coincidía con la
|
|
61
|
+
realidad y proponía un `ALTER COLUMN ... TYPE` en cada ejecución aunque el tipo no hubiera cambiado — inofensivo
|
|
62
|
+
la mayoría de las veces (Postgres permite "cambiar" una columna a su mismo tipo), pero rechazado de plano si otra
|
|
63
|
+
columna `GENERATED` depende de la columna "alterada"; ahora se compara por el tipo canónico
|
|
64
|
+
(`Columna._tipo_base()`). (2) `ManagerDB.aplicar_cambios()` — la ruta que se usa en la primera sincronización de
|
|
65
|
+
una base de datos nueva — creaba todas las tablas del modelo y a continuación las volvía a comparar todas,
|
|
66
|
+
incluidas las que acababa de crear en la misma llamada; una tabla recién creada coincide por definición con el
|
|
67
|
+
modelo que la creó, así que ahora se excluye de esa comparación (que solo tiene sentido sobre tablas
|
|
68
|
+
preexistentes). Esta segunda corrección evita esta clase entera de falsos positivos, no solo el caso ya visto.
|
|
57
69
|
- **0.1.3**: corrige un bug bloqueante en `comparar_generar_alter` — al crear una tabla nueva con una columna
|
|
58
70
|
`GENERATED ALWAYS AS (...) STORED` (p.ej. una columna de búsqueda `tsvector` calculada a partir de otra), la
|
|
59
71
|
siguiente pasada de comparación la trataba como una columna normal (la introspección no reconstruye la expresión
|
|
@@ -34,6 +34,18 @@ pip install -e .
|
|
|
34
34
|
|
|
35
35
|
## Historial
|
|
36
36
|
|
|
37
|
+
- **0.1.4**: corrige la causa de fondo del bug de la 0.1.3, que solo tapaba el síntoma en la columna generada
|
|
38
|
+
en sí. Había dos problemas relacionados: (1) `comparar_generar_alter` comparaba el tipo de columna por su
|
|
39
|
+
nombre "en crudo" (`col.tipo`), así que un modelo que usa alias como `INT`, `TINYINT` o `DATETIME` (en vez de
|
|
40
|
+
`INTEGER`/`SMALLINT`/`TIMESTAMP`, que es como se reconstruyen siempre desde Postgres) nunca coincidía con la
|
|
41
|
+
realidad y proponía un `ALTER COLUMN ... TYPE` en cada ejecución aunque el tipo no hubiera cambiado — inofensivo
|
|
42
|
+
la mayoría de las veces (Postgres permite "cambiar" una columna a su mismo tipo), pero rechazado de plano si otra
|
|
43
|
+
columna `GENERATED` depende de la columna "alterada"; ahora se compara por el tipo canónico
|
|
44
|
+
(`Columna._tipo_base()`). (2) `ManagerDB.aplicar_cambios()` — la ruta que se usa en la primera sincronización de
|
|
45
|
+
una base de datos nueva — creaba todas las tablas del modelo y a continuación las volvía a comparar todas,
|
|
46
|
+
incluidas las que acababa de crear en la misma llamada; una tabla recién creada coincide por definición con el
|
|
47
|
+
modelo que la creó, así que ahora se excluye de esa comparación (que solo tiene sentido sobre tablas
|
|
48
|
+
preexistentes). Esta segunda corrección evita esta clase entera de falsos positivos, no solo el caso ya visto.
|
|
37
49
|
- **0.1.3**: corrige un bug bloqueante en `comparar_generar_alter` — al crear una tabla nueva con una columna
|
|
38
50
|
`GENERATED ALWAYS AS (...) STORED` (p.ej. una columna de búsqueda `tsvector` calculada a partir de otra), la
|
|
39
51
|
siguiente pasada de comparación la trataba como una columna normal (la introspección no reconstruye la expresión
|
|
@@ -129,14 +129,25 @@ class Columna:
|
|
|
129
129
|
}
|
|
130
130
|
_SIN_SOPORTE = {"GEOMETRY", "POINT", "LINESTRING", "POLYGON"}
|
|
131
131
|
|
|
132
|
-
def
|
|
133
|
-
"""
|
|
132
|
+
def _tipo_base(self) -> str:
|
|
133
|
+
"""
|
|
134
|
+
Nombre canónico del tipo en Postgres (sin longitud/precisión), p.ej. "INT" y "INTEGER"
|
|
135
|
+
devuelven ambos "INTEGER". Se usa tanto para generar SQL como para comparar el tipo del
|
|
136
|
+
modelo contra el tipo reconstruido desde la base de datos (obtener_columnas_postgres ya
|
|
137
|
+
siempre devuelve el nombre canónico) — comparar por el nombre "en crudo" haría que un
|
|
138
|
+
modelo que usa alias tipo "INT"/"TINYINT"/"DATETIME" nunca coincidiera con la realidad y
|
|
139
|
+
disparara un ALTER COLUMN de tipo en cada ejecución, aunque el tipo real no haya cambiado.
|
|
140
|
+
"""
|
|
134
141
|
tipo_upper = self.tipo.upper()
|
|
135
142
|
if tipo_upper in self._SIN_SOPORTE:
|
|
136
143
|
raise NotImplementedError(
|
|
137
144
|
f"El tipo '{tipo_upper}' requiere la extensión PostGIS y no está soportado."
|
|
138
145
|
)
|
|
139
|
-
|
|
146
|
+
return self._MAPA_TIPOS.get(tipo_upper, tipo_upper)
|
|
147
|
+
|
|
148
|
+
def _tipo_sql(self) -> str:
|
|
149
|
+
"""Traduce self.tipo (+ longitud/precision/escala) al tipo SQL de Postgres."""
|
|
150
|
+
base = self._tipo_base()
|
|
140
151
|
|
|
141
152
|
if base == "VECTOR":
|
|
142
153
|
if self.longitud is None:
|
|
@@ -750,8 +761,14 @@ class Tabla:
|
|
|
750
761
|
return (val_real, val_def) in equivalentes or (val_def, val_real) in equivalentes or val_real == val_def
|
|
751
762
|
|
|
752
763
|
def tipos_iguales(col_real, col_def):
|
|
764
|
+
# Comparar por el tipo CANÓNICO (col._tipo_base()), no por el texto crudo de col.tipo:
|
|
765
|
+
# el modelo puede usar alias como "INT"/"TINYINT"/"DATETIME" que Postgres no distingue
|
|
766
|
+
# de "INTEGER"/"SMALLINT"/"TIMESTAMP" — comparando el texto crudo, esas columnas nunca
|
|
767
|
+
# coincidirían con la realidad y se propondría un ALTER COLUMN ... TYPE en cada
|
|
768
|
+
# ejecución aunque el tipo real no cambie (inofensivo casi siempre, pero Postgres lo
|
|
769
|
+
# rechaza si otra columna GENERATED depende de la columna "alterada").
|
|
753
770
|
return (
|
|
754
|
-
|
|
771
|
+
col_real._tipo_base() == col_def._tipo_base() and
|
|
755
772
|
col_real.longitud == col_def.longitud and
|
|
756
773
|
col_real.precision == col_def.precision and
|
|
757
774
|
(col_real.escala or None) == (col_def.escala or None)
|
|
@@ -1207,6 +1224,21 @@ class ManagerDB(Database):
|
|
|
1207
1224
|
)
|
|
1208
1225
|
""")
|
|
1209
1226
|
|
|
1227
|
+
# Tablas que ya existían ANTES de esta llamada: solo tiene sentido comparar
|
|
1228
|
+
# (y potencialmente ALTERar) esas. Una tabla recién creada en esta misma llamada
|
|
1229
|
+
# coincide por definición con el modelo que la creó — compararla igual puede
|
|
1230
|
+
# disparar un ALTER falso-positivo (p.ej. no detecta que "INT" y "INTEGER" son el
|
|
1231
|
+
# mismo tipo) que además Postgres puede rechazar de plano si hay una columna
|
|
1232
|
+
# GENERATED que depende de la columna "alterada".
|
|
1233
|
+
tablas_preexistentes = set()
|
|
1234
|
+
for nombre_tabla in self.tablas:
|
|
1235
|
+
cursor.execute(
|
|
1236
|
+
"SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = %s",
|
|
1237
|
+
(nombre_tabla,)
|
|
1238
|
+
)
|
|
1239
|
+
if cursor.fetchone():
|
|
1240
|
+
tablas_preexistentes.add(nombre_tabla)
|
|
1241
|
+
|
|
1210
1242
|
# --- Crear tablas nuevas (+ índices + comentarios) ---
|
|
1211
1243
|
for nombre_tabla, tabla in self.tablas.items():
|
|
1212
1244
|
sentencias_creacion = [tabla.to_sql()] + tabla.to_sql_indices() + tabla.to_sql_comentarios()
|
|
@@ -1218,8 +1250,10 @@ class ManagerDB(Database):
|
|
|
1218
1250
|
if self.logger:
|
|
1219
1251
|
self.logger.info(f"Tabla \"{nombre_tabla}\": ejecutado CREATE IF NOT EXISTS.")
|
|
1220
1252
|
|
|
1221
|
-
# --- Aplicar ALTERs ---
|
|
1253
|
+
# --- Aplicar ALTERs (solo en tablas que ya existían antes de esta llamada) ---
|
|
1222
1254
|
for nombre_tabla, tabla in self.tablas.items():
|
|
1255
|
+
if nombre_tabla not in tablas_preexistentes:
|
|
1256
|
+
continue
|
|
1223
1257
|
alter_sqls = tabla.comparar_generar_alter(conexion, permitir_drop=permitir_drop)
|
|
1224
1258
|
for alter_sql in alter_sqls:
|
|
1225
1259
|
cursor.execute(alter_sql)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mtpk_postgres
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Librería para sincronización estructural de bases de datos Postgres con modelos Python (adaptación de mtpk_mariadb)
|
|
5
5
|
Author-email: José Jesús Andrés Zambrana <jjandres@multiplika.es>
|
|
6
6
|
License: MIT
|
|
@@ -54,6 +54,18 @@ pip install -e .
|
|
|
54
54
|
|
|
55
55
|
## Historial
|
|
56
56
|
|
|
57
|
+
- **0.1.4**: corrige la causa de fondo del bug de la 0.1.3, que solo tapaba el síntoma en la columna generada
|
|
58
|
+
en sí. Había dos problemas relacionados: (1) `comparar_generar_alter` comparaba el tipo de columna por su
|
|
59
|
+
nombre "en crudo" (`col.tipo`), así que un modelo que usa alias como `INT`, `TINYINT` o `DATETIME` (en vez de
|
|
60
|
+
`INTEGER`/`SMALLINT`/`TIMESTAMP`, que es como se reconstruyen siempre desde Postgres) nunca coincidía con la
|
|
61
|
+
realidad y proponía un `ALTER COLUMN ... TYPE` en cada ejecución aunque el tipo no hubiera cambiado — inofensivo
|
|
62
|
+
la mayoría de las veces (Postgres permite "cambiar" una columna a su mismo tipo), pero rechazado de plano si otra
|
|
63
|
+
columna `GENERATED` depende de la columna "alterada"; ahora se compara por el tipo canónico
|
|
64
|
+
(`Columna._tipo_base()`). (2) `ManagerDB.aplicar_cambios()` — la ruta que se usa en la primera sincronización de
|
|
65
|
+
una base de datos nueva — creaba todas las tablas del modelo y a continuación las volvía a comparar todas,
|
|
66
|
+
incluidas las que acababa de crear en la misma llamada; una tabla recién creada coincide por definición con el
|
|
67
|
+
modelo que la creó, así que ahora se excluye de esa comparación (que solo tiene sentido sobre tablas
|
|
68
|
+
preexistentes). Esta segunda corrección evita esta clase entera de falsos positivos, no solo el caso ya visto.
|
|
57
69
|
- **0.1.3**: corrige un bug bloqueante en `comparar_generar_alter` — al crear una tabla nueva con una columna
|
|
58
70
|
`GENERATED ALWAYS AS (...) STORED` (p.ej. una columna de búsqueda `tsvector` calculada a partir de otra), la
|
|
59
71
|
siguiente pasada de comparación la trataba como una columna normal (la introspección no reconstruye la expresión
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mtpk_postgres"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.4"
|
|
8
8
|
description = "Librería para sincronización estructural de bases de datos Postgres con modelos Python (adaptación de mtpk_mariadb)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|