Hi, I've trying to connect to my real MSSQL database in docker with the following fixtures. I omit the DB creation part for now just to simplify things. But I can't connect even to the existed database.
@pytest.fixture(scope="session")
def app():
app = create_app(config_class=TestingConfig)
return app
@pytest.fixture(scope="session")
def _db(app):
"""
Provide the transactional fixtures with access to the database via
a Flask-SQLAlchemy database connection.
"""
db = SQLAlchemy(app=app)
return db
I've tried to use different connection timeout settings but still have the Login timeout expired error
Full stacktrace:
```
ERROR
test setup failed
self = Engine(mssql+pyodbc:///?odbc_connect=Driver%3D%7BODBC+Driver+17+for+SQL+Server%7D%3BServer%3Dtcp%3Adb%2C1433%3BDatabase%3Dsqldb-web-prod-001%3BUid%3Dsa%3BPwd%3DCl1mat3m1nd%21%3BEncrypt%3Dno%3BTrustServerCertificate%3Dno%3B)
fn = >
connection = None
def _wrap_pool_connect(self, fn, connection):
dialect = self.dialect
try:
> return fn()
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2338:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
def unique_connection(self):
"""Produce a DBAPI connection that is not referenced by any
thread-local context.
This method is equivalent to :meth:`_pool.Pool.connect` when the
:paramref:`_pool.Pool.use_threadlocal` flag is not set to True.
When :paramref:`_pool.Pool.use_threadlocal` is True, the
:meth:`_pool.Pool.unique_connection`
method provides a means of bypassing
the threadlocal context.
"""
> return _ConnectionFairy._checkout(self)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:304:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls =
pool =
threadconns = None, fairy = None
@classmethod
def _checkout(cls, pool, threadconns=None, fairy=None):
if not fairy:
> fairy = _ConnectionRecord.checkout(pool)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:778:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls =
pool =
@classmethod
def checkout(cls, pool):
> rec = pool._do_get()
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:495:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
def _do_get(self):
use_overflow = self._max_overflow > -1
try:
wait = use_overflow and self._overflow >= self._max_overflow
return self._pool.get(wait, self._timeout)
except sqla_queue.Empty:
# don't do things inside of "except Empty", because when we say
# we timed out or can't connect and raise, Python 3 tells
# people the real error is queue.Empty which it isn't.
pass
if use_overflow and self._overflow >= self._max_overflow:
if not wait:
return self._do_get()
else:
raise exc.TimeoutError(
"QueuePool limit of size %d overflow %d reached, "
"connection timed out, timeout %d"
% (self.size(), self.overflow(), self._timeout),
code="3o7r",
)
if self._inc_overflow():
try:
return self._create_connection()
except:
with util.safe_reraise():
> self._dec_overflow()
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py:140:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
type_ = None, value = None, traceback = None
def __exit__(self, type_, value, traceback):
# see #2703 for notes
if type_ is None:
exc_type, exc_value, exc_tb = self._exc_info
self._exc_info = None # remove potential circular references
if not self.warn_only:
> compat.raise_(
exc_value, with_traceback=exc_tb,
)
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py:68:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def raise_(
exception, with_traceback=None, replace_context=None, from_=False
):
r"""implement "raise" with cause support.
:param exception: exception to raise
:param with_traceback: will call exception.with_traceback()
:param replace_context: an as-yet-unsupported feature. This is
an exception object which we are "replacing", e.g., it's our
"cause" but we don't want it printed. Basically just what
``__suppress_context__`` does but we don't want to suppress
the enclosing context, if any. So for now we make it the
cause.
:param from\_: the cause. this actually sets the cause and doesn't
hope to hide it someday.
"""
if with_traceback is not None:
exception = exception.with_traceback(with_traceback)
if from_ is not False:
exception.__cause__ = from_
elif replace_context is not None:
# no good solution here, we would like to have the exception
# have only the context of replace_context.__context__ so that the
# intermediary exception does not change, but we can't figure
# that out.
exception.__cause__ = replace_context
try:
> raise exception
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py:182:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
def _do_get(self):
use_overflow = self._max_overflow > -1
try:
wait = use_overflow and self._overflow >= self._max_overflow
return self._pool.get(wait, self._timeout)
except sqla_queue.Empty:
# don't do things inside of "except Empty", because when we say
# we timed out or can't connect and raise, Python 3 tells
# people the real error is queue.Empty which it isn't.
pass
if use_overflow and self._overflow >= self._max_overflow:
if not wait:
return self._do_get()
else:
raise exc.TimeoutError(
"QueuePool limit of size %d overflow %d reached, "
"connection timed out, timeout %d"
% (self.size(), self.overflow(), self._timeout),
code="3o7r",
)
if self._inc_overflow():
try:
> return self._create_connection()
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py:137:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
def _create_connection(self):
"""Called by subclasses to create a new ConnectionRecord."""
> return _ConnectionRecord(self)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:309:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
pool = , connect = True
def __init__(self, pool, connect=True):
self.__pool = pool
if connect:
> self.__connect(first_connect_check=True)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:440:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
first_connect_check = True
def __connect(self, first_connect_check=False):
pool = self.__pool
# ensure any existing connection is removed, so that if
# creator fails, this attribute stays None
self.connection = None
try:
self.starttime = time.time()
connection = pool._invoke_creator(self)
pool.logger.debug("Created new connection %r", connection)
self.connection = connection
except Exception as e:
with util.safe_reraise():
> pool.logger.debug("Error on connect(): %s", e)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:661:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
type_ = None, value = None, traceback = None
def __exit__(self, type_, value, traceback):
# see #2703 for notes
if type_ is None:
exc_type, exc_value, exc_tb = self._exc_info
self._exc_info = None # remove potential circular references
if not self.warn_only:
> compat.raise_(
exc_value, with_traceback=exc_tb,
)
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py:68:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def raise_(
exception, with_traceback=None, replace_context=None, from_=False
):
r"""implement "raise" with cause support.
:param exception: exception to raise
:param with_traceback: will call exception.with_traceback()
:param replace_context: an as-yet-unsupported feature. This is
an exception object which we are "replacing", e.g., it's our
"cause" but we don't want it printed. Basically just what
``__suppress_context__`` does but we don't want to suppress
the enclosing context, if any. So for now we make it the
cause.
:param from\_: the cause. this actually sets the cause and doesn't
hope to hide it someday.
"""
if with_traceback is not None:
exception = exception.with_traceback(with_traceback)
if from_ is not False:
exception.__cause__ = from_
elif replace_context is not None:
# no good solution here, we would like to have the exception
# have only the context of replace_context.__context__ so that the
# intermediary exception does not change, but we can't figure
# that out.
exception.__cause__ = replace_context
try:
> raise exception
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py:182:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
first_connect_check = True
def __connect(self, first_connect_check=False):
pool = self.__pool
# ensure any existing connection is removed, so that if
# creator fails, this attribute stays None
self.connection = None
try:
self.starttime = time.time()
> connection = pool._invoke_creator(self)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:656:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
connection_record =
def connect(connection_record=None):
if dialect._has_events:
for fn in dialect.dispatch.do_connect:
connection = fn(
dialect, connection_record, cargs, cparams
)
if connection is not None:
return connection
> return dialect.connect(*cargs, **cparams)
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/strategies.py:114:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
cargs = ('Driver={ODBC Driver 17 for SQL Server};Server=tcp:db,1433;Database=sqldb-web-prod-001;Uid=sa;Pwd=Cl1mat3m1nd!;Encrypt=no;TrustServerCertificate=no;',)
cparams = {}
def connect(self, *cargs, **cparams):
# inherits the docstring from interfaces.Dialect.connect
> return self.dbapi.connect(*cargs, **cparams)
E pyodbc.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/default.py:493: OperationalError
The above exception was the direct cause of the following exception:
request = >
def fill(request):
item = request._pyfuncitem
fixturenames = getattr(item, "fixturenames", None)
if fixturenames is None:
fixturenames = request.fixturenames
if hasattr(item, 'callspec'):
for param, val in sorted_by_dependency(item.callspec.params, fixturenames):
if val is not None and is_lazy_fixture(val):
item.callspec.params[param] = request.getfixturevalue(val.name)
elif param not in item.funcargs:
item.funcargs[param] = request.getfixturevalue(param)
> _fillfixtures()
/usr/local/lib/python3.8/site-packages/pytest_lazyfixture.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.8/site-packages/pytest_flask_sqlalchemy/fixtures.py:31: in _transaction
connection = _db.engine.connect()
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2265: in connect
return self._connection_cls(self, **kwargs)
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py:104: in __init__
else engine.raw_connection()
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2371: in raw_connection
return self._wrap_pool_connect(
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2341: in _wrap_pool_connect
Connection._handle_dbapi_exception_noconnection(
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py:1583: in _handle_dbapi_exception_noconnection
util.raise_(
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py:182: in raise_
raise exception
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/base.py:2338: in _wrap_pool_connect
return fn()
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:304: in unique_connection
return _ConnectionFairy._checkout(self)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:778: in _checkout
fairy = _ConnectionRecord.checkout(pool)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:495: in checkout
rec = pool._do_get()
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py:140: in _do_get
self._dec_overflow()
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py:68: in __exit__
compat.raise_(
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py:182: in raise_
raise exception
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/impl.py:137: in _do_get
return self._create_connection()
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:309: in _create_connection
return _ConnectionRecord(self)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:440: in __init__
self.__connect(first_connect_check=True)
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:661: in __connect
pool.logger.debug("Error on connect(): %s", e)
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py:68: in __exit__
compat.raise_(
/usr/local/lib/python3.8/site-packages/sqlalchemy/util/compat.py:182: in raise_
raise exception
/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/base.py:656: in __connect
connection = pool._invoke_creator(self)
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/strategies.py:114: in connect
return dialect.connect(*cargs, **cparams)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
cargs = ('Driver={ODBC Driver 17 for SQL Server};Server=tcp:db,1433;Database=sqldb-web-prod-001;Uid=sa;Pwd=Cl1mat3m1nd!;Encrypt=no;TrustServerCertificate=no;',)
cparams = {}
def connect(self, *cargs, **cparams):
# inherits the docstring from interfaces.Dialect.connect
> return self.dbapi.connect(*cargs, **cparams)
E sqlalchemy.exc.OperationalError: (pyodbc.OperationalError) ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
E (Background on this error at: http://sqlalche.me/e/13/e3q8)
/usr/local/lib/python3.8/site-packages/sqlalchemy/engine/default.py:493: OperationalError
```
Hi, I've trying to connect to my real MSSQL database in docker with the following fixtures. I omit the DB creation part for now just to simplify things. But I can't connect even to the existed database.
I've tried to use different
connection timeout
settings but still have theLogin timeout expired
error Full stacktrace: