tlocke / pg8000

A Pure-Python PostgreSQL Driver
BSD 3-Clause "New" or "Revised" License
515 stars 46 forks source link

Intermittent `struct.error` instead of `InterfaceError` attempting to connect to initializing database. #102

Closed pedantic-curmudgeon closed 2 years ago

pedantic-curmudgeon commented 2 years ago

Hello!

I've been encountering an intermittent issue where a struct.error is being raised instead of an InterfaceError when attempting to connect to a PostgreSQL Docker container when it is first being initialized. Sometimes I get the struct.error and other times I get the expected InterfaceError, which I'm expecting and have logic to handle.

I haven't yet been able to replicate the issue on my local machine, but I am encountering it on and off when running in a GitHub workflow using a hosted runner.

If this is expected behavior, I can always just catch the struct.error in addition to the InterfaceError, but I wanted to confirm first.

Thanks in advance and for the great library!

GitHub Runner VM:

SQL Alchemy Connection:

URL = f'postgresql+pg8000://{USER}:{PASSWORD}@{SERVER}:{PORT}/{DB}'
TEST_DB_ENGINE = create_engine(URL)

Connection Validation:

waited = 0
while waited <= timeout:
    try:
        with TEST_DB_ENGINE.begin():
            return True
    except InterfaceError:
        waited += interval
        sleep(interval)
return False

Error:

Traceback (most recent call last):
Starting test suite.
  File "/home/runner/work/skyward_flight/skyward_flight/tests/run_test_suite.py", line 111, in <module>
Starting database test-db.
    run_test_suite()
  File "/home/runner/work/skyward_flight/skyward_flight/tests/run_test_suite.py", line 104, in run_test_suite
    _start_test_db()
  File "/home/runner/work/skyward_flight/skyward_flight/tests/run_test_suite.py", line 36, in _start_test_db
    if not _test_db_active():
  File "/home/runner/work/skyward_flight/skyward_flight/tests/run_test_suite.py", line 56, in _test_db_active
    with TEST_DB_ENGINE.begin():
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3062, in begin
    conn = self.connect(close_with_result=close_with_result)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3234, in connect
    return self._connection_cls(self, close_with_result=close_with_result)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 96, in __init__
    else engine.raw_connection()
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3313, in raw_connection
    return self._wrap_pool_connect(self.pool.connect, _connection)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 3280, in _wrap_pool_connect
    return fn()
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 310, in connect
    return _ConnectionFairy._checkout(self)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 868, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 476, in checkout
    rec = pool._do_get()
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/impl.py", line 145, in _do_get
    with util.safe_reraise():
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    compat.raise_(
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/impl.py", line 143, in _do_get
    return self._create_connection()
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 256, in _create_connection
    return _ConnectionRecord(self)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 371, in __init__
    self.__connect()
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 665, in __connect
    with util.safe_reraise():
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    compat.raise_(
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/pool/base.py", line 661, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/engine/create.py", line 590, in connect
    return dialect.connect(*cargs, **cparams)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 597, in connect
    return self.dbapi.connect(*cargs, **cparams)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/pg8000/__init__.py", line 117, in connect
    return Connection(
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/pg8000/legacy.py", line 442, in __init__
    super().__init__(*args, **kwargs)
  File "/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/pg8000/core.py", line 339, in __init__
    code, data_len = ci_unpack(self._read(5))
struct.error: unpack_from requires a buffer of at least 5 bytes for unpacking 5 bytes at offset 0 (actual buffer size is 0)
tlocke commented 2 years ago

Hi @pedantic-curmudgeon, thanks for the bug report. It should be fixed now in the latest release (1.26.0), but let me know if it's still a problem.

pedantic-curmudgeon commented 2 years ago

Thanks, @tlocke! I'll update on my side and re-test.

pedantic-curmudgeon commented 2 years ago

@tlocke I updated to 1.26.0 and everything looks good to go! Thanks again!