Compatibility with psycopg 3.0 (#2088)

By default `psycopg2` is preferred. The `psycopg>=3.0` will be used only if `psycopg2` is not available or its version is too old.
This commit is contained in:
Alexander Kukushkin
2021-11-19 14:32:54 +01:00
committed by GitHub
parent edfe2a84e9
commit fce889cd04
30 changed files with 231 additions and 138 deletions
+10 -8
View File
@@ -1,12 +1,14 @@
import datetime
import os
import psutil
import psycopg2
import re
import subprocess
import time
from mock import Mock, MagicMock, PropertyMock, patch, mock_open
import patroni.psycopg as psycopg
from patroni.async_executor import CriticalTask
from patroni.dcs import Cluster, RemoteMember, SyncState
from patroni.exceptions import PostgresConnectionException, PatroniException
@@ -17,7 +19,7 @@ from patroni.utils import RetryFailedError
from six.moves import builtins
from threading import Thread, current_thread
from . import BaseTestPostgresql, MockCursor, MockPostmaster, psycopg2_connect
from . import BaseTestPostgresql, MockCursor, MockPostmaster, psycopg_connect
mtime_ret = {}
@@ -87,7 +89,7 @@ Data page checksum version: 0
@patch('subprocess.call', Mock(return_value=0))
@patch('psycopg2.connect', psycopg2_connect)
@patch('patroni.psycopg.connect', psycopg_connect)
class TestPostgresql(BaseTestPostgresql):
@patch('subprocess.call', Mock(return_value=0))
@@ -319,7 +321,7 @@ class TestPostgresql(BaseTestPostgresql):
m = RemoteMember('1', {'restore_command': '2', 'primary_slot_name': 'foo', 'conn_kwargs': {'host': 'bar'}})
self.p.follow(m)
@patch.object(MockCursor, 'execute', Mock(side_effect=psycopg2.OperationalError))
@patch.object(MockCursor, 'execute', Mock(side_effect=psycopg.OperationalError))
def test__query(self):
self.assertRaises(PostgresConnectionException, self.p._query, 'blabla')
self.p._state = 'restarting'
@@ -328,7 +330,7 @@ class TestPostgresql(BaseTestPostgresql):
def test_query(self):
self.p.query('select 1')
self.assertRaises(PostgresConnectionException, self.p.query, 'RetryFailedError')
self.assertRaises(psycopg2.ProgrammingError, self.p.query, 'blabla')
self.assertRaises(psycopg.ProgrammingError, self.p.query, 'blabla')
@patch.object(Postgresql, 'pg_isready', Mock(return_value=STATE_REJECT))
def test_is_leader(self):
@@ -430,7 +432,7 @@ class TestPostgresql(BaseTestPostgresql):
@patch.object(Postgresql, 'is_running', Mock(return_value=MockPostmaster()))
def test_is_leader_exception(self):
self.p.start()
self.p.query = Mock(side_effect=psycopg2.OperationalError("not supported"))
self.p.query = Mock(side_effect=psycopg.OperationalError("not supported"))
self.assertTrue(self.p.stop())
@patch('os.rename', Mock())
@@ -559,7 +561,7 @@ class TestPostgresql(BaseTestPostgresql):
t.start()
t.join()
with patch.object(MockCursor, "execute", side_effect=psycopg2.Error):
with patch.object(MockCursor, "execute", side_effect=psycopg.Error):
self.assertIsNone(self.p.postmaster_start_time())
def test_check_for_startup(self):
@@ -722,7 +724,7 @@ class TestPostgresql(BaseTestPostgresql):
self.p.stop(on_safepoint=mock_callback)
mock_postmaster.is_running.side_effect = [True, False, False]
with patch.object(MockCursor, "execute", Mock(side_effect=psycopg2.Error)):
with patch.object(MockCursor, "execute", Mock(side_effect=psycopg.Error)):
self.p.stop(on_safepoint=mock_callback)
def test_terminate_starting_postmaster(self):