pum 1.3.0__tar.gz → 1.3.1__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.
Files changed (44) hide show
  1. {pum-1.3.0 → pum-1.3.1}/PKG-INFO +1 -1
  2. {pum-1.3.0 → pum-1.3.1}/pum/schema_migrations.py +19 -23
  3. {pum-1.3.0 → pum-1.3.1}/pum.egg-info/PKG-INFO +1 -1
  4. {pum-1.3.0 → pum-1.3.1}/pum.egg-info/SOURCES.txt +0 -1
  5. pum-1.3.0/test/test_transaction_fix.py +0 -100
  6. {pum-1.3.0 → pum-1.3.1}/LICENSE +0 -0
  7. {pum-1.3.0 → pum-1.3.1}/README.md +0 -0
  8. {pum-1.3.0 → pum-1.3.1}/pum/__init__.py +0 -0
  9. {pum-1.3.0 → pum-1.3.1}/pum/changelog.py +0 -0
  10. {pum-1.3.0 → pum-1.3.1}/pum/checker.py +0 -0
  11. {pum-1.3.0 → pum-1.3.1}/pum/cli.py +0 -0
  12. {pum-1.3.0 → pum-1.3.1}/pum/config_model.py +0 -0
  13. {pum-1.3.0 → pum-1.3.1}/pum/connection.py +0 -0
  14. {pum-1.3.0 → pum-1.3.1}/pum/dependency_handler.py +0 -0
  15. {pum-1.3.0 → pum-1.3.1}/pum/dumper.py +0 -0
  16. {pum-1.3.0 → pum-1.3.1}/pum/exceptions.py +0 -0
  17. {pum-1.3.0 → pum-1.3.1}/pum/feedback.py +0 -0
  18. {pum-1.3.0 → pum-1.3.1}/pum/hook.py +0 -0
  19. {pum-1.3.0 → pum-1.3.1}/pum/info.py +0 -0
  20. {pum-1.3.0 → pum-1.3.1}/pum/parameter.py +0 -0
  21. {pum-1.3.0 → pum-1.3.1}/pum/pum_config.py +0 -0
  22. {pum-1.3.0 → pum-1.3.1}/pum/report_generator.py +0 -0
  23. {pum-1.3.0 → pum-1.3.1}/pum/role_manager.py +0 -0
  24. {pum-1.3.0 → pum-1.3.1}/pum/sql_content.py +0 -0
  25. {pum-1.3.0 → pum-1.3.1}/pum/upgrader.py +0 -0
  26. {pum-1.3.0 → pum-1.3.1}/pum.egg-info/dependency_links.txt +0 -0
  27. {pum-1.3.0 → pum-1.3.1}/pum.egg-info/entry_points.txt +0 -0
  28. {pum-1.3.0 → pum-1.3.1}/pum.egg-info/requires.txt +0 -0
  29. {pum-1.3.0 → pum-1.3.1}/pum.egg-info/top_level.txt +0 -0
  30. {pum-1.3.0 → pum-1.3.1}/pyproject.toml +0 -0
  31. {pum-1.3.0 → pum-1.3.1}/requirements/base.txt +0 -0
  32. {pum-1.3.0 → pum-1.3.1}/requirements/development.txt +0 -0
  33. {pum-1.3.0 → pum-1.3.1}/requirements/html.txt +0 -0
  34. {pum-1.3.0 → pum-1.3.1}/setup.cfg +0 -0
  35. {pum-1.3.0 → pum-1.3.1}/test/test_changelog.py +0 -0
  36. {pum-1.3.0 → pum-1.3.1}/test/test_checker.py +0 -0
  37. {pum-1.3.0 → pum-1.3.1}/test/test_config.py +0 -0
  38. {pum-1.3.0 → pum-1.3.1}/test/test_dumper.py +0 -0
  39. {pum-1.3.0 → pum-1.3.1}/test/test_feedback.py +0 -0
  40. {pum-1.3.0 → pum-1.3.1}/test/test_hooks.py +0 -0
  41. {pum-1.3.0 → pum-1.3.1}/test/test_roles.py +0 -0
  42. {pum-1.3.0 → pum-1.3.1}/test/test_schema_migrations.py +0 -0
  43. {pum-1.3.0 → pum-1.3.1}/test/test_sql_content.py +0 -0
  44. {pum-1.3.0 → pum-1.3.1}/test/test_upgrader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pum
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: Pum stands for "Postgres Upgrades Manager". It is a Database migration management tool very similar to flyway-db or Liquibase, based on metadata tables.
5
5
  Author-email: Denis Rouzaud <denis@opengis.ch>
6
6
  License-Expression: GPL-2.0-or-later
@@ -74,10 +74,9 @@ class SchemaMigrations:
74
74
  "schema": psycopg.sql.Literal(self.config.config.pum.migration_table_schema),
75
75
  }
76
76
 
77
- with connection.transaction():
78
- cursor = SqlContent(query).execute(connection, parameters=parameters)
79
- result = cursor._pum_results[0] if cursor._pum_results else None
80
- return result[0] if result else False
77
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
78
+ result = cursor._pum_results[0] if cursor._pum_results else None
79
+ return result[0] if result else False
81
80
 
82
81
  def exists_in_other_schemas(self, connection: psycopg.Connection) -> list[str]:
83
82
  """Check if the schema_migrations information table exists in other schemas.
@@ -100,9 +99,8 @@ class SchemaMigrations:
100
99
  parameters = {
101
100
  "schema": psycopg.sql.Literal(self.config.config.pum.migration_table_schema),
102
101
  }
103
- with connection.transaction():
104
- cursor = SqlContent(query).execute(connection, parameters=parameters)
105
- return [row[0] for row in (cursor._pum_results or [])]
102
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
103
+ return [row[0] for row in (cursor._pum_results or [])]
106
104
 
107
105
  def create(
108
106
  self,
@@ -346,14 +344,13 @@ INSERT INTO {table} (
346
344
  "table": self.migration_table_identifier,
347
345
  }
348
346
 
349
- with connection.transaction():
350
- cursor = SqlContent(query).execute(connection, parameters=parameters)
351
- row = cursor._pum_results[0] if cursor._pum_results else None
352
- if row is None:
353
- raise PumSchemaMigrationNoBaselineError(
354
- f"Baseline version not found in the {self.migration_table_identifier_str} table."
355
- )
356
- return packaging.version.parse(row[0])
347
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
348
+ row = cursor._pum_results[0] if cursor._pum_results else None
349
+ if row is None:
350
+ raise PumSchemaMigrationNoBaselineError(
351
+ f"Baseline version not found in the {self.migration_table_identifier_str} table."
352
+ )
353
+ return packaging.version.parse(row[0])
357
354
 
358
355
  def migration_details(self, connection: psycopg.Connection, version: str | None = None) -> dict:
359
356
  """Return the migration details from the migration table.
@@ -404,14 +401,13 @@ INSERT INTO {table} (
404
401
  "version": psycopg.sql.Literal(version),
405
402
  }
406
403
 
407
- with connection.transaction():
408
- cursor = SqlContent(query).execute(connection, parameters=parameters)
409
- row = cursor._pum_results[0] if cursor._pum_results else None
410
- if row is None:
411
- raise PumSchemaMigrationError(
412
- f"Migration details not found for version {version} in the {self.migration_table_identifier_str} table."
413
- )
414
- return dict(zip([desc[0] for desc in cursor._pum_description], row, strict=False))
404
+ cursor = SqlContent(query).execute(connection, parameters=parameters)
405
+ row = cursor._pum_results[0] if cursor._pum_results else None
406
+ if row is None:
407
+ raise PumSchemaMigrationError(
408
+ f"Migration details not found for version {version} in the {self.migration_table_identifier_str} table."
409
+ )
410
+ return dict(zip([desc[0] for desc in cursor._pum_description], row, strict=False))
415
411
 
416
412
  def compare(self, connection: psycopg.Connection) -> int:
417
413
  """Compare the migrations details in the database to the changelogs in the source.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pum
3
- Version: 1.3.0
3
+ Version: 1.3.1
4
4
  Summary: Pum stands for "Postgres Upgrades Manager". It is a Database migration management tool very similar to flyway-db or Liquibase, based on metadata tables.
5
5
  Author-email: Denis Rouzaud <denis@opengis.ch>
6
6
  License-Expression: GPL-2.0-or-later
@@ -38,5 +38,4 @@ test/test_hooks.py
38
38
  test/test_roles.py
39
39
  test/test_schema_migrations.py
40
40
  test/test_sql_content.py
41
- test/test_transaction_fix.py
42
41
  test/test_upgrader.py
@@ -1,100 +0,0 @@
1
- import unittest
2
- from pathlib import Path
3
-
4
- import psycopg
5
-
6
- from pum.pum_config import PumConfig
7
- from pum.schema_migrations import SchemaMigrations
8
-
9
-
10
- class TestTransactionFix(unittest.TestCase):
11
- """Test that verifies the transaction fix prevents 'idle in transaction' state."""
12
-
13
- def setUp(self) -> None:
14
- """Set up the test environment."""
15
- self.pg_service = "pum_test"
16
-
17
- def test_schema_migrations_exists_transaction_state(self) -> None:
18
- """Test that schema_migrations.exists() doesn't leave connection in 'idle in transaction'."""
19
- test_dir = Path("test") / "data" / "single_changelog"
20
- cfg = PumConfig(test_dir, pum={"module": "test_single_changelog"})
21
- sm = SchemaMigrations(cfg)
22
-
23
- with psycopg.connect(f"service={self.pg_service}") as conn:
24
- # Clean up any existing table
25
- with conn.transaction():
26
- conn.execute("DROP TABLE IF EXISTS public.pum_migrations")
27
-
28
- # Initial state should be IDLE
29
- self.assertEqual(conn.info.transaction_status.name, "IDLE")
30
-
31
- # Call exists() which executes a query
32
- sm.exists(conn)
33
-
34
- # After the call, connection should still be IDLE (not "IDLE_IN_TRANSACTION")
35
- # This will FAIL if the transaction block is not used in exists()
36
- transaction_status = conn.info.transaction_status.name
37
- self.assertEqual(
38
- transaction_status,
39
- "IDLE",
40
- f"Connection in '{transaction_status}' state after exists() - should use transaction block",
41
- )
42
-
43
- def test_schema_migrations_baseline_transaction_state(self) -> None:
44
- """Test that schema_migrations.baseline() doesn't leave connection in 'idle in transaction'."""
45
- test_dir = Path("test") / "data" / "single_changelog"
46
- cfg = PumConfig(test_dir, pum={"module": "test_single_changelog"})
47
- sm = SchemaMigrations(cfg)
48
-
49
- with psycopg.connect(f"service={self.pg_service}") as conn:
50
- # Create the migrations table with some data
51
- with conn.transaction():
52
- sm.create(conn)
53
- sm.set_baseline(conn, "1.0.0", commit=False)
54
-
55
- # Initial state should be IDLE
56
- self.assertEqual(conn.info.transaction_status.name, "IDLE")
57
-
58
- # Call baseline() which executes a query
59
- sm.baseline(conn)
60
-
61
- # After the call, connection should still be IDLE
62
- transaction_status = conn.info.transaction_status.name
63
- self.assertEqual(
64
- transaction_status,
65
- "IDLE",
66
- f"Connection in '{transaction_status}' state after baseline() - should use transaction block",
67
- )
68
-
69
- # Clean up
70
- with conn.transaction():
71
- conn.execute("DROP TABLE IF EXISTS public.pum_migrations")
72
-
73
- def test_multiple_queries_without_transaction_causes_idle_in_transaction(self) -> None:
74
- """Test that demonstrates the problem: queries without transaction blocks cause 'idle in transaction'."""
75
- with psycopg.connect(f"service={self.pg_service}") as conn:
76
- # Start with IDLE state
77
- self.assertEqual(conn.info.transaction_status.name, "IDLE")
78
-
79
- # Execute a query WITHOUT using a transaction block
80
- # This simulates the old buggy behavior
81
- cursor = conn.cursor()
82
- cursor.execute("SELECT 1")
83
- cursor.fetchone()
84
- cursor.close()
85
-
86
- # Now the connection is stuck in INTRANS (idle in transaction)
87
- transaction_status = conn.info.transaction_status.name
88
- self.assertEqual(
89
- transaction_status,
90
- "INTRANS",
91
- "Without transaction blocks, connection gets stuck in INTRANS (idle in transaction)",
92
- )
93
-
94
- # Need to explicitly commit to get back to IDLE
95
- conn.commit()
96
- self.assertEqual(conn.info.transaction_status.name, "IDLE")
97
-
98
-
99
- if __name__ == "__main__":
100
- unittest.main()
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
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
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
File without changes
File without changes
File without changes
File without changes
File without changes