Skip to content

Commit d32ec21

Browse files
committed
Show server_version
1 parent 46a19c5 commit d32ec21

File tree

2 files changed

+22
-33
lines changed

2 files changed

+22
-33
lines changed

sqlmesh/core/engine_adapter/postgres.py

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
import re
55
import typing as t
6-
from functools import partial
6+
from functools import cached_property, partial
77
from sqlglot import exp
88

99
from sqlmesh.core.engine_adapter.base_postgres import BasePostgresEngineAdapter
@@ -113,7 +113,7 @@ def merge(
113113
**kwargs: t.Any,
114114
) -> None:
115115
# Merge isn't supported until Postgres 15
116-
major, minor = self.get_server_version()
116+
major, minor = self.server_version
117117
merge_impl = super().merge if major >= 15 else partial(logical_merge, self)
118118
merge_impl( # type: ignore
119119
target_table,
@@ -124,22 +124,11 @@ def merge(
124124
merge_filter=merge_filter,
125125
)
126126

127-
def get_server_version(self) -> t.Tuple[int, int]:
128-
"""Return major and minor server versions of the connection"""
129-
connection = self._connection_pool.get()
130-
connection_module = connection.__class__.__module__
131-
if connection_module.startswith("pg8000"):
132-
server_version = connection.parameter_statuses.get("server_version")
133-
# pg8000 server version contains version as well as packaging and distribution information
134-
# e.g. 15.13 (Debian 15.13-1.pgdg120+1)
135-
match = re.search(r"(\d+)\.(\d+)", server_version)
136-
if match:
137-
return int(match.group(1)), int(match.group(2))
138-
elif connection_module.startswith("psycopg"):
139-
# This handles both psycopg and psycopg2 connection objects
140-
server_version = connection.info.server_version
141-
# Since major version 10, PostgreSQL represents the server version with an integer by
142-
# multiplying the server's major version number by 10000 and adding the minor version number
143-
# See https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQSERVERVERSION
144-
return server_version // 10000, server_version % 100
127+
@cached_property
128+
def server_version(self) -> t.Tuple[int, int]:
129+
"""Lazily fetch and cache major and minor server version"""
130+
server_version, *_ = self.fetchone("SHOW server_version")
131+
match = re.search(r"(\d+)\.(\d+)", server_version)
132+
if match:
133+
return int(match.group(1)), int(match.group(2))
145134
return 0, 0

tests/core/engine_adapter/test_postgres.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,7 @@ def test_create_table_like(make_mocked_engine_adapter: t.Callable):
9494

9595
def test_merge_version_gte_15(make_mocked_engine_adapter: t.Callable):
9696
adapter = make_mocked_engine_adapter(PostgresEngineAdapter)
97-
adapter._connection_pool.get().__class__.__module__ = "psycopg2.extensions"
98-
adapter._connection_pool.get().info.server_version = 150000
97+
adapter.server_version = (15, 0)
9998

10099
adapter.merge(
101100
target_table="target",
@@ -118,8 +117,7 @@ def test_merge_version_lt_15(
118117
make_mocked_engine_adapter: t.Callable, make_temp_table_name: t.Callable, mocker: MockerFixture
119118
):
120119
adapter = make_mocked_engine_adapter(PostgresEngineAdapter)
121-
adapter._connection_pool.get().__class__.__module__ = "psycopg2.extensions"
122-
adapter._connection_pool.get().info.server_version = 140000
120+
adapter.server_version = (14, 0)
123121

124122
temp_table_mock = mocker.patch("sqlmesh.core.engine_adapter.EngineAdapter._get_temp_table")
125123
table_name = "test"
@@ -165,15 +163,17 @@ def table_columns(table_name: str) -> t.Dict[str, exp.DataType]:
165163
]
166164

167165

168-
def test_get_server_version(make_mocked_engine_adapter: t.Callable):
166+
def test_server_version(make_mocked_engine_adapter: t.Callable, mocker: MockerFixture):
169167
adapter = make_mocked_engine_adapter(PostgresEngineAdapter)
170168

171-
adapter._connection_pool.get().__class__.__module__ = "psycopg2.extensions"
172-
adapter._connection_pool.get().info.server_version = 150013
173-
assert adapter.get_server_version() == (15, 13)
169+
fetchone_mock = mocker.patch.object(adapter, "fetchone")
170+
fetchone_mock.return_value = ("14.0",)
171+
assert adapter.server_version == (14, 0)
174172

175-
adapter._connection_pool.get().__class__.__module__ = "pg8000.native"
176-
adapter._connection_pool.get().parameter_statuses = {
177-
"server_version": "15.13 (Debian 15.13-1.pgdg120+1)"
178-
}
179-
assert adapter.get_server_version() == (15, 13)
173+
del adapter.server_version
174+
fetchone_mock.return_value = ("15.8",)
175+
assert adapter.server_version == (15, 8)
176+
177+
del adapter.server_version
178+
fetchone_mock.return_value = ("15.13 (Debian 15.13-1.pgdg120+1)",)
179+
assert adapter.server_version == (15, 13)

0 commit comments

Comments
 (0)