pgdevkit 0.6.1__tar.gz → 0.6.2__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 (127) hide show
  1. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/PKG-INFO +1 -1
  2. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/constants.py +7 -0
  3. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/container.py +6 -1
  4. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pyproject.toml +1 -1
  5. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_container.py +40 -0
  6. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/uv.lock +1 -1
  7. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/.github/workflows/auto-release.yml +0 -0
  8. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/.github/workflows/python-publish.yml +0 -0
  9. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/.github/workflows/python-test.yml +0 -0
  10. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/.gitignore +0 -0
  11. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/.python-version +0 -0
  12. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/README.md +0 -0
  13. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/docs/database-layout.md +0 -0
  14. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/__init__.py +0 -0
  15. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/areas.py +0 -0
  16. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/backends/__init__.py +0 -0
  17. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/backends/base.py +0 -0
  18. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/backends/mssql.py +0 -0
  19. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/backends/postgres.py +0 -0
  20. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/cli.py +0 -0
  21. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/connection.py +0 -0
  22. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/__init__.py +0 -0
  23. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/complex_types.py +0 -0
  24. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/connection.py +0 -0
  25. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/crud.py +0 -0
  26. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/loader.py +0 -0
  27. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/model.py +0 -0
  28. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/mssql_crud.py +0 -0
  29. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/db/mssql_sql.py +0 -0
  30. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/dialect.py +0 -0
  31. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/diff.py +0 -0
  32. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/envtag.py +0 -0
  33. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/fetch_missing.py +0 -0
  34. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/introspect.py +0 -0
  35. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/lakebase.py +0 -0
  36. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/migrate.py +0 -0
  37. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/models.py +0 -0
  38. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/mssql_introspect.py +0 -0
  39. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/parser.py +0 -0
  40. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/schemas.py +0 -0
  41. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/sql_text.py +0 -0
  42. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/__init__.py +0 -0
  43. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/_docker.py +0 -0
  44. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/api.py +0 -0
  45. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/config.py +0 -0
  46. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/mssql/__init__.py +0 -0
  47. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/mssql/api.py +0 -0
  48. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/mssql/constants.py +0 -0
  49. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/mssql/container.py +0 -0
  50. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/naming.py +0 -0
  51. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/query.py +0 -0
  52. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/pgdevkit/testdb/schema.py +0 -0
  53. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/skills/pgdevkit/SKILL.md +0 -0
  54. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/skills/pgdevkit/references/dynamic-sql.md +0 -0
  55. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/skills/pgdevkit/references/temporal-tables.md +0 -0
  56. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/__init__.py +0 -0
  57. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/conftest.py +0 -0
  58. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/db/__init__.py +0 -0
  59. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/db/test_complex_types.py +0 -0
  60. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/db/test_connection.py +0 -0
  61. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/db/test_crud.py +0 -0
  62. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/db/test_loader.py +0 -0
  63. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/db/test_mssql_crud_live.py +0 -0
  64. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/db/test_mssql_crud_sql.py +0 -0
  65. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/fixtures/01_schema.sql +0 -0
  66. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/fixtures/02_types.sql +0 -0
  67. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/fixtures/03_tables.sql +0 -0
  68. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/fixtures/04_views.sql +0 -0
  69. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/fixtures/05_functions.sql +0 -0
  70. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/fixtures/06_indexes.sql +0 -0
  71. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_areas.py +0 -0
  72. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_cli_compare.py +0 -0
  73. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_compare.py +0 -0
  74. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_compare_mssql_live.py +0 -0
  75. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_connection.py +0 -0
  76. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_dialect.py +0 -0
  77. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_diff_mssql.py +0 -0
  78. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_envtag.py +0 -0
  79. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_fetch_missing.py +0 -0
  80. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_fetch_missing_cli.py +0 -0
  81. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_lakebase.py +0 -0
  82. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_migrate.py +0 -0
  83. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_migrate_areas.py +0 -0
  84. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_migrate_env.py +0 -0
  85. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_migrate_schemas.py +0 -0
  86. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_mssql_introspect.py +0 -0
  87. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_parser_areas.py +0 -0
  88. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_parser_mssql.py +0 -0
  89. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_parser_schemas.py +0 -0
  90. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/test_schemas.py +0 -0
  91. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/__init__.py +0 -0
  92. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/conftest.py +0 -0
  93. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/migrations/001_add_gadget_note.sql +0 -0
  94. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/event.sql +0 -0
  95. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/event_kind.sql +0 -0
  96. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/gadget.sql +0 -0
  97. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/gadget.test_data.json +0 -0
  98. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/prod_only.prod.sql +0 -0
  99. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/widget.init.sql +0 -0
  100. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/widget.sql +0 -0
  101. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/widget.test_data.json +0 -0
  102. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/widget_part.sql +0 -0
  103. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/tables/widget_part_detail.sql +0 -0
  104. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/types/dimensions.sql +0 -0
  105. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/types/mood.sql +0 -0
  106. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/views/a_wrapper_view.sql +0 -0
  107. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/app/views/b_base_view.sql +0 -0
  108. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/permissions/grants.sql +0 -0
  109. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database/schema/app.sql +0 -0
  110. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database_mssql/app/tables/widget.sql +0 -0
  111. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database_mssql/app/tables/widget.test_data.json +0 -0
  112. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database_mssql/app/views/a_wrapper_view.sql +0 -0
  113. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database_mssql/app/views/b_base_view.sql +0 -0
  114. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/fixtures/database_mssql/schema/app.sql +0 -0
  115. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_api.py +0 -0
  116. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_api_mssql.py +0 -0
  117. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_api_mssql_live.py +0 -0
  118. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_cli.py +0 -0
  119. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_config.py +0 -0
  120. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_config_mssql.py +0 -0
  121. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_constants.py +0 -0
  122. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_mssql_constants.py +0 -0
  123. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_naming.py +0 -0
  124. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_query.py +0 -0
  125. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_schema.py +0 -0
  126. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_schema_filtering.py +0 -0
  127. {pgdevkit-0.6.1 → pgdevkit-0.6.2}/tests/testdb/test_schema_mssql.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pgdevkit
3
- Version: 0.6.1
3
+ Version: 0.6.2
4
4
  Summary: A helper for developing with Postgres
5
5
  Requires-Python: >=3.14
6
6
  Requires-Dist: docker>=7.1.0
@@ -11,6 +11,13 @@ PORT = int(os.environ.get("PGDEVKIT_TESTDB_PORT", "54322"))
11
11
  USER = os.environ.get("PGDEVKIT_TESTDB_USER", "postgres")
12
12
  PASSWORD = os.environ.get("PGDEVKIT_TESTDB_PASSWORD", "testpwd")
13
13
  PG_SPEED_FLAGS = ["-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
14
+ # Production connects with session timezone=UTC; the container image's own default
15
+ # (baked into its base OS, not something pgdevkit ever set) can differ, silently
16
+ # making any ::date cast of a timestamptz column disagree between test and prod for
17
+ # rows near local midnight. Forcing UTC here -- both as the server's own timezone GUC
18
+ # and as PGTZ/TZ for any client library that consults the environment instead -- keeps
19
+ # test parity with prod instead of depending on the host/image's locale.
20
+ PG_STARTUP_FLAGS = [*PG_SPEED_FLAGS, "-c", "timezone=UTC"]
14
21
 
15
22
 
16
23
  def conninfo(dbname: str, *, connect_timeout: int | None = None) -> str:
@@ -36,8 +36,13 @@ def _create_container(client: docker.DockerClient) -> None:
36
36
  environment={
37
37
  "POSTGRES_USER": constants.USER,
38
38
  "POSTGRES_PASSWORD": constants.PASSWORD,
39
+ # Belt-and-suspenders alongside the server's own -c timezone=UTC below:
40
+ # some client libraries/tools inside the container consult TZ/PGTZ
41
+ # directly instead of asking Postgres for its configured timezone.
42
+ "TZ": "UTC",
43
+ "PGTZ": "UTC",
39
44
  },
40
- command=["postgres", *constants.PG_SPEED_FLAGS],
45
+ command=["postgres", *constants.PG_STARTUP_FLAGS],
41
46
  )
42
47
  except docker.errors.APIError as e:
43
48
  if getattr(e, "status_code", None) == 409 or "already in use" in str(e):
@@ -11,7 +11,7 @@ packages = ["pgdevkit"]
11
11
 
12
12
  [project]
13
13
  name = "pgdevkit"
14
- version = "0.6.1"
14
+ version = "0.6.2"
15
15
  description = "A helper for developing with Postgres"
16
16
  readme = "README.md"
17
17
  requires-python = ">=3.14"
@@ -49,6 +49,36 @@ def test_ensure_container_skips_everything_when_skip_env_set(monkeypatch):
49
49
  ensure_container() # must return without checking availability or calling the Docker API
50
50
 
51
51
 
52
+ class _FakeContainers:
53
+ def __init__(self):
54
+ self.run_kwargs: dict | None = None
55
+
56
+ def run(self, image, **kwargs):
57
+ self.run_kwargs = kwargs
58
+
59
+
60
+ class _FakeClient:
61
+ def __init__(self):
62
+ self.containers = _FakeContainers()
63
+
64
+
65
+ def test_create_container_forces_utc_timezone():
66
+ """Test Postgres must run with timezone=UTC regardless of the container
67
+ image's/host's own locale default -- production connects with session
68
+ timezone=UTC, so any ::date cast of a timestamptz column would otherwise
69
+ silently disagree between test and prod for rows near local midnight."""
70
+ client = _FakeClient()
71
+
72
+ _create_container(client)
73
+
74
+ assert client.containers.run_kwargs is not None
75
+ assert "-c" in client.containers.run_kwargs["command"]
76
+ timezone_flag_index = client.containers.run_kwargs["command"].index("timezone=UTC")
77
+ assert client.containers.run_kwargs["command"][timezone_flag_index - 1] == "-c"
78
+ assert client.containers.run_kwargs["environment"]["TZ"] == "UTC"
79
+ assert client.containers.run_kwargs["environment"]["PGTZ"] == "UTC"
80
+
81
+
52
82
  def _admin_dsn() -> str:
53
83
  return constants.conninfo("postgres", connect_timeout=5)
54
84
 
@@ -84,3 +114,13 @@ def test_create_container_falls_back_to_start_when_name_in_use():
84
114
  with con.cursor() as cur:
85
115
  cur.execute("SELECT 1")
86
116
  assert cur.fetchone() == (1,)
117
+
118
+
119
+ @requires_podman
120
+ def test_ensure_container_runs_with_utc_timezone():
121
+ ensure_container()
122
+
123
+ with psycopg.connect(_admin_dsn()) as con:
124
+ with con.cursor() as cur:
125
+ cur.execute("SHOW timezone")
126
+ assert cur.fetchone() == ("UTC",)
@@ -313,7 +313,7 @@ wheels = [
313
313
 
314
314
  [[package]]
315
315
  name = "pgdevkit"
316
- version = "0.6.1"
316
+ version = "0.6.2"
317
317
  source = { editable = "." }
318
318
  dependencies = [
319
319
  { name = "docker" },
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