.. sourcecode:: pycon+sql
>>> ins = users.insert()
- >>> conn.execute(ins, id=2, name='wendy', fullname='Wendy Williams')
+ >>> conn.execute(ins, {"id": 2, "name":"wendy", "fullname": "Wendy Williams"})
{opensql}INSERT INTO users (id, name, fullname) VALUES (?, ?, ?)
[...] (2, 'wendy', 'Wendy Williams')
COMMIT
... "AND users.name BETWEEN :x AND :y "
... "AND (addresses.email_address LIKE :e1 "
... "OR addresses.email_address LIKE :e2)")
- >>> conn.execute(s, x='m', y='z', e1='%@aol.com', e2='%@msn.com').fetchall()
+ >>> conn.execute(s, {"x":"m", "y":"z", "e1":"%@aol.com", "e2":"%@msn.com"}).fetchall()
{opensql}SELECT users.fullname || ', ' || addresses.email_address AS title
FROM users, addresses
WHERE users.id = addresses.user_id AND users.name BETWEEN ? AND ? AND
... "OR addresses.email_address LIKE :y)")
... )
... ).select_from(text('users, addresses'))
- >>> conn.execute(s, x='%@aol.com', y='%@msn.com').fetchall()
+ >>> conn.execute(s, {"x": "%@aol.com", "y": "%@msn.com"}).fetchall()
{opensql}SELECT users.fullname || ', ' || addresses.email_address AS title
FROM users, addresses
WHERE users.id = addresses.user_id AND users.name BETWEEN 'm' AND 'z'
... )
... ).select_from(table('users')).select_from(table('addresses'))
- >>> conn.execute(s, x='%@aol.com', y='%@msn.com').fetchall()
+ >>> conn.execute(s, {"x":"%@aol.com", "y":"%@msn.com"}).fetchall()
{opensql}SELECT users.fullname || ? || addresses.email_address AS anon_1
FROM users, addresses
WHERE users.id = addresses.user_id
// TODO: pass the Connection in so that there can be a standard
// method for warning on parameter format
- PyObject *multiparams, *params;
+ PyObject *connection, *multiparams, *params;
PyObject *enclosing_list, *double_enclosing_list;
PyObject *zero_element, *zero_element_item;
+ PyObject *tmp;
Py_ssize_t multiparam_size, zero_element_length;
- if (!PyArg_UnpackTuple(args, "_distill_params", 2, 2, &multiparams, ¶ms)) {
+ if (!PyArg_UnpackTuple(args, "_distill_params", 3, 3, &connection, &multiparams, ¶ms)) {
return NULL;
}
if (multiparam_size == 0) {
if (params != Py_None && PyMapping_Size(params) != 0) {
- // TODO: this is keyword parameters, emit parameter format
- // deprecation warning
+
+ tmp = PyObject_CallMethod(connection, "_warn_for_legacy_exec_format", "");
+ if (tmp == NULL) {
+ return NULL;
+ }
+
enclosing_list = PyList_New(1);
if (enclosing_list == NULL) {
return NULL;
* execute(stmt, ("value", "value"))
*/
Py_XDECREF(zero_element_item);
+
enclosing_list = PyList_New(1);
if (enclosing_list == NULL) {
return NULL;
}
return enclosing_list;
} else {
+ tmp = PyObject_CallMethod(connection, "_warn_for_legacy_exec_format", "");
+ if (tmp == NULL) {
+ return NULL;
+ }
+
enclosing_list = PyList_New(1);
if (enclosing_list == NULL) {
return NULL;
}
}
else {
- // TODO: this is multiple positional params, emit parameter format
- // deprecation warning
+
+ tmp = PyObject_CallMethod(connection, "_warn_for_legacy_exec_format", "");
+ if (tmp == NULL) {
+ return NULL;
+ }
+
zero_element = PyTuple_GetItem(multiparams, 0);
if (PyObject_HasAttrString(zero_element, "__iter__") &&
!PyObject_HasAttrString(zero_element, "strip")
"JOIN pg_namespace n ON n.oid = c.relnamespace "
"WHERE n.nspname = :schema AND c.relkind in ('r', 'p')"
).columns(relname=sqltypes.Unicode),
- schema=schema if schema is not None else self.default_schema_name,
+ dict(
+ schema=schema
+ if schema is not None
+ else self.default_schema_name
+ ),
)
return [name for name, in result]
.bindparams(sql.bindparam("table_oid", type_=sqltypes.Integer))
.columns(attname=sqltypes.Unicode, default=sqltypes.Unicode)
)
- c = connection.execute(s, table_oid=table_oid)
+ c = connection.execute(s, dict(table_oid=table_oid))
rows = c.fetchall()
# dictionary with (name, ) if default search path or (schema, name)
ORDER BY k.ord
"""
t = sql.text(PK_SQL).columns(attname=sqltypes.Unicode)
- c = connection.execute(t, table_oid=table_oid)
+ c = connection.execute(t, dict(table_oid=table_oid))
cols = [r[0] for r in c.fetchall()]
PK_CONS_SQL = """
ORDER BY 1
"""
t = sql.text(PK_CONS_SQL).columns(conname=sqltypes.Unicode)
- c = connection.execute(t, table_oid=table_oid)
+ c = connection.execute(t, dict(table_oid=table_oid))
name = c.scalar()
return {"constrained_columns": cols, "name": name}
t = sql.text(FK_SQL).columns(
conname=sqltypes.Unicode, condef=sqltypes.Unicode
)
- c = connection.execute(t, table=table_oid)
+ c = connection.execute(t, dict(table=table_oid))
fkeys = []
for conname, condef, conschema in c.fetchall():
m = re.search(FK_REGEX, condef).groups()
t = sql.text(IDX_SQL).columns(
relname=sqltypes.Unicode, attname=sqltypes.Unicode
)
- c = connection.execute(t, table_oid=table_oid)
+ c = connection.execute(t, dict(table_oid=table_oid))
indexes = defaultdict(lambda: defaultdict(dict))
"""
t = sql.text(UNIQUE_SQL).columns(col_name=sqltypes.Unicode)
- c = connection.execute(t, table_oid=table_oid)
+ c = connection.execute(t, dict(table_oid=table_oid))
uniques = defaultdict(lambda: defaultdict(dict))
for row in c.fetchall():
cons.contype = 'c'
"""
- c = connection.execute(sql.text(CHECK_SQL), table_oid=table_oid)
+ c = connection.execute(sql.text(CHECK_SQL), dict(table_oid=table_oid))
ret = []
for name, src in c:
if not self.in_transaction():
self._rollback_impl()
+ def _warn_for_legacy_exec_format(self):
+ util.warn_deprecated_20(
+ "The connection.execute() method in "
+ "SQLAlchemy 2.0 will accept parameters as a single "
+ "dictionary or a "
+ "single sequence of dictionaries only. "
+ "Parameters passed as keyword arguments, tuples or positionally "
+ "oriened dictionaries and/or tuples "
+ "will no longer be accepted."
+ )
+
def close(self):
"""Close this :class:`_engine.Connection`.
"or the Connection.exec_driver_sql() method to invoke a "
"driver-level SQL string."
)
- distilled_parameters = _distill_params(multiparams, params)
return self._exec_driver_sql(
object_,
multiparams,
params,
- distilled_parameters,
_EMPTY_EXECUTION_OPTS,
+ future=False,
)
try:
execution_options
)
+ distilled_parameters = _distill_params(self, multiparams, params)
+
if self._has_events or self.engine._has_events:
- for fn in self.dispatch.before_execute:
- default, multiparams, params = fn(
- self, default, multiparams, params, execution_options
- )
+ (
+ distilled_params,
+ event_multiparams,
+ event_params,
+ ) = self._invoke_before_exec_event(
+ default, distilled_parameters, execution_options
+ )
try:
conn = self._dbapi_connection
if self._has_events or self.engine._has_events:
self.dispatch.after_execute(
- self, default, multiparams, params, execution_options, ret
+ self,
+ default,
+ event_multiparams,
+ event_params,
+ execution_options,
+ ret,
)
return ret
self._execution_options, execution_options
)
+ distilled_parameters = _distill_params(self, multiparams, params)
+
if self._has_events or self.engine._has_events:
- for fn in self.dispatch.before_execute:
- ddl, multiparams, params = fn(
- self, ddl, multiparams, params, execution_options
- )
+ (
+ distilled_params,
+ event_multiparams,
+ event_params,
+ ) = self._invoke_before_exec_event(
+ ddl, distilled_parameters, execution_options
+ )
exec_opts = self._execution_options.merge_with(execution_options)
schema_translate_map = exec_opts.get("schema_translate_map", None)
)
if self._has_events or self.engine._has_events:
self.dispatch.after_execute(
- self, ddl, multiparams, params, execution_options, ret
+ self,
+ ddl,
+ event_multiparams,
+ event_params,
+ execution_options,
+ ret,
)
return ret
+ def _invoke_before_exec_event(
+ self, elem, distilled_params, execution_options
+ ):
+
+ if len(distilled_params) == 1:
+ event_multiparams, event_params = [], distilled_params[0]
+ else:
+ event_multiparams, event_params = distilled_params, {}
+
+ for fn in self.dispatch.before_execute:
+ elem, event_multiparams, event_params = fn(
+ self, elem, event_multiparams, event_params, execution_options,
+ )
+
+ if event_multiparams:
+ distilled_params = list(event_multiparams)
+ if event_params:
+ raise exc.InvalidRequestError(
+ "Event handler can't return non-empty multiparams "
+ "and params at the same time"
+ )
+ elif event_params:
+ distilled_params = [event_params]
+ else:
+ distilled_params = []
+
+ return distilled_params, event_multiparams, event_params
+
def _execute_clauseelement(
self, elem, multiparams, params, execution_options
):
self._execution_options, execution_options
)
+ distilled_params = _distill_params(self, multiparams, params)
+
has_events = self._has_events or self.engine._has_events
if has_events:
- for fn in self.dispatch.before_execute:
- elem, multiparams, params = fn(
- self, elem, multiparams, params, execution_options
- )
+ (
+ distilled_params,
+ event_multiparams,
+ event_params,
+ ) = self._invoke_before_exec_event(
+ elem, distilled_params, execution_options
+ )
- distilled_params = _distill_params(multiparams, params)
if distilled_params:
# ensure we don't retain a link to the view object for keys()
# which links to the values, which we don't want to cache
)
if has_events:
self.dispatch.after_execute(
- self, elem, multiparams, params, execution_options, ret
+ self,
+ elem,
+ event_multiparams,
+ event_params,
+ execution_options,
+ ret,
)
return ret
execution_options = compiled.execution_options.merge_with(
self._execution_options, execution_options
)
+ distilled_parameters = _distill_params(self, multiparams, params)
if self._has_events or self.engine._has_events:
- for fn in self.dispatch.before_execute:
- compiled, multiparams, params = fn(
- self, compiled, multiparams, params, execution_options
- )
+ (
+ distilled_params,
+ event_multiparams,
+ event_params,
+ ) = self._invoke_before_exec_event(
+ compiled, distilled_parameters, execution_options
+ )
dialect = self.dialect
- parameters = _distill_params(multiparams, params)
ret = self._execute_context(
dialect,
dialect.execution_ctx_cls._init_compiled,
compiled,
- parameters,
+ distilled_parameters,
execution_options,
compiled,
- parameters,
+ distilled_parameters,
None,
None,
)
if self._has_events or self.engine._has_events:
self.dispatch.after_execute(
- self, compiled, multiparams, params, execution_options, ret
+ self,
+ compiled,
+ event_multiparams,
+ event_params,
+ execution_options,
+ ret,
)
return ret
def _exec_driver_sql(
- self,
- statement,
- multiparams,
- params,
- distilled_parameters,
- execution_options,
+ self, statement, multiparams, params, execution_options, future
):
execution_options = self._execution_options.merge_with(
execution_options
)
- if self._has_events or self.engine._has_events:
- for fn in self.dispatch.before_execute:
- statement, multiparams, params = fn(
- self, statement, multiparams, params, execution_options
+ distilled_parameters = _distill_params(self, multiparams, params)
+
+ if not future:
+ if self._has_events or self.engine._has_events:
+ (
+ distilled_params,
+ event_multiparams,
+ event_params,
+ ) = self._invoke_before_exec_event(
+ statement, distilled_parameters, execution_options
)
dialect = self.dialect
statement,
distilled_parameters,
)
- if self._has_events or self.engine._has_events:
- self.dispatch.after_execute(
- self, statement, multiparams, params, execution_options, ret
- )
+
+ if not future:
+ if self._has_events or self.engine._has_events:
+ self.dispatch.after_execute(
+ self,
+ statement,
+ event_multiparams,
+ event_params,
+ execution_options,
+ ret,
+ )
return ret
def _execute_20(
parameters=None,
execution_options=_EMPTY_EXECUTION_OPTS,
):
- multiparams, params, distilled_parameters = _distill_params_20(
- parameters
- )
+ args_10style, kwargs_10style = _distill_params_20(parameters)
try:
meth = statement._execute_on_connection
except AttributeError as err:
exc.ObjectNotExecutableError(statement), replace_context=err
)
else:
- return meth(self, multiparams, params, execution_options)
+ return meth(self, args_10style, kwargs_10style, execution_options)
def exec_driver_sql(
self, statement, parameters=None, execution_options=None
(1, 'v1')
)
+ .. note:: The :meth:`_engine.Connection.exec_driver_sql` method does
+ not participate in the
+ :meth:`_events.ConnectionEvents.before_execute` and
+ :meth:`_events.ConnectionEvents.after_execute` events. To
+ intercept calls to :meth:`_engine.Connection.exec_driver_sql`, use
+ :meth:`_events.ConnectionEvents.before_cursor_execute` and
+ :meth:`_events.ConnectionEvents.after_cursor_execute`.
+
.. seealso::
:pep:`249`
"""
- multiparams, params, distilled_parameters = _distill_params_20(
- parameters
- )
+ args_10style, kwargs_10style = _distill_params_20(parameters)
return self._exec_driver_sql(
statement,
- multiparams,
- params,
- distilled_parameters,
+ args_10style,
+ kwargs_10style,
execution_options,
+ future=True,
)
def _execute_context(
return decorated
+_no_tuple = ()
+_no_kw = util.immutabledict()
+
+
def py_fallback():
# TODO: pass the Connection in so that there can be a standard
# method for warning on parameter format
- def _distill_params(multiparams, params): # noqa
+ def _distill_params(connection, multiparams, params): # noqa
r"""Given arguments from the calling form \*multiparams, \**params,
return a list of bind parameter structures, usually a list of
dictionaries.
"""
+ # C version will fail if this assertion is not true.
+ # assert isinstance(multiparams, tuple)
+
if not multiparams:
if params:
- # TODO: parameter format deprecation warning
+ connection._warn_for_legacy_exec_format()
return [params]
else:
return []
# execute(stmt, [(), (), (), ...])
return zero
else:
+ # this is used by exec_driver_sql only, so a deprecation
+ # warning would already be coming from passing a plain
+ # textual statement with positional parameters to
+ # execute().
# execute(stmt, ("value", "value"))
+
return [zero]
elif hasattr(zero, "keys"):
# execute(stmt, {"key":"value"})
return [zero]
else:
+ connection._warn_for_legacy_exec_format()
# execute(stmt, "value")
return [[zero]]
else:
- # TODO: parameter format deprecation warning
+ connection._warn_for_legacy_exec_format()
if hasattr(multiparams[0], "__iter__") and not hasattr(
multiparams[0], "strip"
):
return locals()
-_no_tuple = ()
-_no_kw = util.immutabledict()
+def _distill_cursor_params(connection, multiparams, params):
+ """_distill_params without any warnings. more appropriate for
+ "cursor" params that can include tuple arguments, lists of tuples,
+ etc.
+
+ """
+
+ if not multiparams:
+ if params:
+ return [params]
+ else:
+ return []
+ elif len(multiparams) == 1:
+ zero = multiparams[0]
+ if isinstance(zero, (list, tuple)):
+ if (
+ not zero
+ or hasattr(zero[0], "__iter__")
+ and not hasattr(zero[0], "strip")
+ ):
+ # execute(stmt, [{}, {}, {}, ...])
+ # execute(stmt, [(), (), (), ...])
+ return zero
+ else:
+ # this is used by exec_driver_sql only, so a deprecation
+ # warning would already be coming from passing a plain
+ # textual statement with positional parameters to
+ # execute().
+ # execute(stmt, ("value", "value"))
+
+ return [zero]
+ elif hasattr(zero, "keys"):
+ # execute(stmt, {"key":"value"})
+ return [zero]
+ else:
+ # execute(stmt, "value")
+ return [[zero]]
+ else:
+ if hasattr(multiparams[0], "__iter__") and not hasattr(
+ multiparams[0], "strip"
+ ):
+ return multiparams
+ else:
+ return [multiparams]
def _distill_params_20(params):
- # TODO: this has to be in C
if params is None:
- return _no_tuple, _no_kw, []
+ return _no_tuple, _no_kw
elif isinstance(params, list):
# collections_abc.MutableSequence): # avoid abc.__instancecheck__
if params and not isinstance(
"List argument must consist only of tuples or dictionaries"
)
- # the tuple is needed atm by the C version of _distill_params...
- return tuple(params), _no_kw, params
+ return (params,), _no_kw
elif isinstance(
params,
(tuple, dict, immutabledict),
# avoid abc.__instancecheck__
# (collections_abc.Sequence, collections_abc.Mapping),
):
- return _no_tuple, params, [params]
+ return (params,), _no_kw
else:
raise exc.ArgumentError("mapping or sequence expected for parameters")
from .. import util
from ..engine import url
from ..engine.default import DefaultDialect
-from ..engine.util import _distill_params
+from ..engine.util import _distill_cursor_params
from ..schema import _DDLCompiles
def __init__(self, context, clauseelement, multiparams, params):
self.context = context
self.clauseelement = clauseelement
- self.parameters = _distill_params(multiparams, params)
+ self.parameters = _distill_cursor_params(
+ context.connection, tuple(multiparams), params
+ )
self.statements = []
def __repr__(self):
) as conn:
[tuple(row) for row in conn.execute(t2.select()).fetchall()]
- @profiling.function_call_count(variance=0.10)
+ @profiling.function_call_count(variance=0.15)
def test_raw_string(self):
stmt = "SELECT %s FROM table1" % (
", ".join("field%d" % fnum for fnum in range(NUM_FIELDS))
with testing.db.connect() as conn:
[tuple(row) for row in conn.exec_driver_sql(stmt).fetchall()]
- @profiling.function_call_count(variance=0.10)
+ @profiling.function_call_count(variance=0.15)
def test_raw_unicode(self):
stmt = "SELECT %s FROM table2" % (
", ".join("field%d" % fnum for fnum in range(NUM_FIELDS))
(exc.IntegrityError, exc.ProgrammingError),
conn.execute,
table.insert(),
- {"data": "d2"},
- {"data": "d3"},
+ [{"data": "d2"}, {"data": "d3"}],
)
with expect_warnings(
".*has no Python-side or server-side default.*"
(exc.IntegrityError, exc.ProgrammingError),
conn.execute,
table.insert(),
- {"data": "d2"},
- {"data": "d3"},
+ [{"data": "d2"}, {"data": "d3"}],
)
conn.execute(
table.insert(),
- {"id": 31, "data": "d2"},
- {"id": 32, "data": "d3"},
+ [{"id": 31, "data": "d2"}, {"id": 32, "data": "d3"}],
)
conn.execute(table.insert(inline=True), {"id": 33, "data": "d4"})
eq_(
(exc.IntegrityError, exc.ProgrammingError),
conn.execute,
table.insert(),
- {"data": "d2"},
- {"data": "d3"},
+ [{"data": "d2"}, {"data": "d3"}],
)
conn.execute(
table.insert(),
- {"id": 31, "data": "d2"},
- {"id": 32, "data": "d3"},
+ [{"id": 31, "data": "d2"}, {"id": 32, "data": "d3"}],
)
conn.execute(table.insert(inline=True), {"id": 33, "data": "d4"})
eq_(
from sqlalchemy.testing import is_false
from sqlalchemy.testing import is_instance_of
from sqlalchemy.testing import is_true
+from sqlalchemy.testing import mock
from sqlalchemy.testing.engines import testing_engine
from sqlalchemy.testing.mock import Mock
from sqlalchemy.testing.schema import Column
with _string_deprecation_expect():
testing.db.execute(select1(testing.db)).scalar()
+ def test_execute_plain_string_events(self):
+
+ m1 = Mock()
+ select1_str = select1(testing.db)
+ with _string_deprecation_expect():
+ with testing.db.connect() as conn:
+ event.listen(conn, "before_execute", m1.before_execute)
+ event.listen(conn, "after_execute", m1.after_execute)
+ result = conn.execute(select1_str)
+ eq_(
+ m1.mock_calls,
+ [
+ mock.call.before_execute(mock.ANY, select1_str, [], {}, {}),
+ mock.call.after_execute(
+ mock.ANY, select1_str, [], {}, {}, result
+ ),
+ ],
+ )
+
def test_scalar_plain_string(self):
with _string_deprecation_expect():
testing.db.scalar(select1(testing.db))
]
+class DeprecatedExecParamsTest(fixtures.TablesTest):
+ __backend__ = True
+
+ @classmethod
+ def define_tables(cls, metadata):
+ Table(
+ "users",
+ metadata,
+ Column("user_id", INT, primary_key=True, autoincrement=False),
+ Column("user_name", VARCHAR(20)),
+ )
+
+ Table(
+ "users_autoinc",
+ metadata,
+ Column(
+ "user_id", INT, primary_key=True, test_needs_autoincrement=True
+ ),
+ Column("user_name", VARCHAR(20)),
+ )
+
+ def test_kwargs(self, connection):
+ users = self.tables.users
+
+ with testing.expect_deprecated_20(
+ r"The connection.execute\(\) method in "
+ "SQLAlchemy 2.0 will accept parameters as a single "
+ ):
+ connection.execute(
+ users.insert(), user_id=5, user_name="some name"
+ )
+
+ eq_(connection.execute(select(users)).all(), [(5, "some name")])
+
+ def test_positional_dicts(self, connection):
+ users = self.tables.users
+
+ with testing.expect_deprecated_20(
+ r"The connection.execute\(\) method in "
+ "SQLAlchemy 2.0 will accept parameters as a single "
+ ):
+ connection.execute(
+ users.insert(),
+ {"user_id": 5, "user_name": "some name"},
+ {"user_id": 6, "user_name": "some other name"},
+ )
+
+ eq_(
+ connection.execute(select(users).order_by(users.c.user_id)).all(),
+ [(5, "some name"), (6, "some other name")],
+ )
+
+ def test_single_scalar(self, connection):
+
+ users = self.tables.users_autoinc
+
+ with testing.expect_deprecated_20(
+ r"The connection.execute\(\) method in "
+ "SQLAlchemy 2.0 will accept parameters as a single "
+ ):
+ # TODO: I'm not even sure what this exec format is or how
+ # it worked if at all
+ connection.execute(users.insert(), "some name")
+
+ eq_(
+ connection.execute(select(users).order_by(users.c.user_id)).all(),
+ [(1, None)],
+ )
+
+
class EngineEventsTest(fixtures.TestBase):
__requires__ = ("ad_hoc_engines",)
__backend__ = True
from sqlalchemy.testing import config
from sqlalchemy.testing import engines
from sqlalchemy.testing import eq_
+from sqlalchemy.testing import expect_raises_message
from sqlalchemy.testing import expect_warnings
from sqlalchemy.testing import fixtures
from sqlalchemy.testing import is_
eq_(canary.be1.call_count, 2)
eq_(canary.be2.call_count, 2)
+ def test_new_exec_driver_sql_no_events(self):
+ m1 = Mock()
+
+ def select1(db):
+ return str(select([1]).compile(dialect=db.dialect))
+
+ with testing.db.connect() as conn:
+ event.listen(conn, "before_execute", m1.before_execute)
+ event.listen(conn, "after_execute", m1.after_execute)
+ conn.exec_driver_sql(select1(testing.db))
+ eq_(m1.mock_calls, [])
+
def test_add_event_after_connect(self):
# new feature as of #2978
canary = Mock()
[call(conn, ctx.cursor, stmt, ctx.parameters[0], ctx, False)],
)
+ @testing.combinations(
+ (
+ ([{"x": 5, "y": 10}, {"x": 8, "y": 9}],),
+ {},
+ [{"x": 5, "y": 10}, {"x": 8, "y": 9}],
+ {},
+ ),
+ ((), {"z": 10}, [], {"z": 10}, testing.requires.legacy_engine),
+ (({"z": 10},), {}, [], {"z": 10}),
+ )
+ def test_modify_parameters_from_event_one(
+ self, multiparams, params, expected_multiparams, expected_params
+ ):
+ # this is testing both the normalization added to parameters
+ # as of I97cb4d06adfcc6b889f10d01cc7775925cffb116 as well as
+ # that the return value from the event is taken as the new set
+ # of parameters.
+ def before_execute(
+ conn, clauseelement, multiparams, params, execution_options
+ ):
+ eq_(multiparams, expected_multiparams)
+ eq_(params, expected_params)
+ return clauseelement, (), {"q": "15"}
+
+ def after_execute(
+ conn, clauseelement, multiparams, params, result, execution_options
+ ):
+ eq_(multiparams, ())
+ eq_(params, {"q": "15"})
+
+ e1 = testing_engine(config.db_url)
+ event.listen(e1, "before_execute", before_execute, retval=True)
+ event.listen(e1, "after_execute", after_execute)
+
+ with e1.connect() as conn:
+ result = conn.execute(
+ select(bindparam("q", type_=String)), *multiparams, **params
+ )
+ eq_(result.all(), [("15",)])
+
+ @testing.provide_metadata
+ def test_modify_parameters_from_event_two(self, connection):
+ t = Table("t", self.metadata, Column("q", Integer))
+
+ t.create(connection)
+
+ def before_execute(
+ conn, clauseelement, multiparams, params, execution_options
+ ):
+ return clauseelement, [{"q": 15}, {"q": 19}], {}
+
+ event.listen(connection, "before_execute", before_execute, retval=True)
+ connection.execute(t.insert(), {"q": 12})
+ event.remove(connection, "before_execute", before_execute)
+
+ eq_(
+ connection.execute(select(t).order_by(t.c.q)).fetchall(),
+ [(15,), (19,)],
+ )
+
+ def test_modify_parameters_from_event_three(self, connection):
+ def before_execute(
+ conn, clauseelement, multiparams, params, execution_options
+ ):
+ return clauseelement, [{"q": 15}, {"q": 19}], {"q": 7}
+
+ e1 = testing_engine(config.db_url)
+ event.listen(e1, "before_execute", before_execute, retval=True)
+
+ with expect_raises_message(
+ tsa.exc.InvalidRequestError,
+ "Event handler can't return non-empty multiparams "
+ "and params at the same time",
+ ):
+ with e1.connect() as conn:
+ conn.execute(select(literal("1")))
+
def test_argument_format_execute(self):
def before_execute(
conn, clauseelement, multiparams, params, execution_options
if ctx:
ctx.close()
- if engine._is_future:
- compiled = [
- ("CREATE TABLE t1", {}, None),
- (
- "INSERT INTO t1 (c1, c2)",
- {"c2": "some data", "c1": 5},
- None,
- ),
- ("INSERT INTO t1 (c1, c2)", {"c1": 6}, None),
- ("select * from t1", {}, None),
- ("DROP TABLE t1", {}, None),
- ]
- else:
- compiled = [
- ("CREATE TABLE t1", {}, None),
- (
- "INSERT INTO t1 (c1, c2)",
- {},
- ({"c2": "some data", "c1": 5},),
- ),
- ("INSERT INTO t1 (c1, c2)", {}, ({"c1": 6},)),
- ("select * from t1", {}, None),
- ("DROP TABLE t1", {}, None),
- ]
+ compiled = [
+ ("CREATE TABLE t1", {}, None),
+ ("INSERT INTO t1 (c1, c2)", {"c2": "some data", "c1": 5}, (),),
+ ("INSERT INTO t1 (c1, c2)", {"c1": 6}, ()),
+ ("select * from t1", {}, None),
+ ("DROP TABLE t1", {}, None),
+ ]
cursor = [
("CREATE TABLE t1", {}, ()),
from sqlalchemy.testing import assert_raises_message
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
+from sqlalchemy.testing import mock
class _BooleanProcessorTest(fixtures.TestBase):
class _DistillArgsTest(fixtures.TestBase):
def test_distill_none(self):
- eq_(self.module._distill_params(None, None), [])
+ eq_(self.module._distill_params(mock.Mock(), None, None), [])
def test_distill_no_multi_no_param(self):
- eq_(self.module._distill_params((), {}), [])
+ eq_(self.module._distill_params(mock.Mock(), (), {}), [])
def test_distill_dict_multi_none_param(self):
eq_(
- self.module._distill_params(None, {"foo": "bar"}), [{"foo": "bar"}]
+ self.module._distill_params(mock.Mock(), None, {"foo": "bar"}),
+ [{"foo": "bar"}],
)
def test_distill_dict_multi_empty_param(self):
- eq_(self.module._distill_params((), {"foo": "bar"}), [{"foo": "bar"}])
+ eq_(
+ self.module._distill_params(mock.Mock(), (), {"foo": "bar"}),
+ [{"foo": "bar"}],
+ )
def test_distill_single_dict(self):
eq_(
- self.module._distill_params(({"foo": "bar"},), {}),
+ self.module._distill_params(mock.Mock(), ({"foo": "bar"},), {}),
[{"foo": "bar"}],
)
def test_distill_single_list_strings(self):
eq_(
- self.module._distill_params((["foo", "bar"],), {}),
+ self.module._distill_params(mock.Mock(), (["foo", "bar"],), {}),
[["foo", "bar"]],
)
def test_distill_single_list_tuples(self):
eq_(
self.module._distill_params(
- ([("foo", "bar"), ("bat", "hoho")],), {}
+ mock.Mock(), ([("foo", "bar"), ("bat", "hoho")],), {}
),
[("foo", "bar"), ("bat", "hoho")],
)
def test_distill_single_list_tuple(self):
eq_(
- self.module._distill_params(([("foo", "bar")],), {}),
+ self.module._distill_params(mock.Mock(), ([("foo", "bar")],), {}),
[("foo", "bar")],
)
def test_distill_multi_list_tuple(self):
eq_(
self.module._distill_params(
- ([("foo", "bar")], [("bar", "bat")]), {}
+ mock.Mock(), ([("foo", "bar")], [("bar", "bat")]), {}
),
([("foo", "bar")], [("bar", "bat")]),
)
def test_distill_multi_strings(self):
- eq_(self.module._distill_params(("foo", "bar"), {}), [("foo", "bar")])
+ eq_(
+ self.module._distill_params(mock.Mock(), ("foo", "bar"), {}),
+ [("foo", "bar")],
+ )
def test_distill_single_list_dicts(self):
eq_(
self.module._distill_params(
- ([{"foo": "bar"}, {"foo": "hoho"}],), {}
+ mock.Mock(), ([{"foo": "bar"}, {"foo": "hoho"}],), {}
),
[{"foo": "bar"}, {"foo": "hoho"}],
)
def test_distill_single_string(self):
- eq_(self.module._distill_params(("arg",), {}), [["arg"]])
+ eq_(self.module._distill_params(mock.Mock(), ("arg",), {}), [["arg"]])
def test_distill_multi_string_tuple(self):
eq_(
- self.module._distill_params((("arg", "arg"),), {}),
+ self.module._distill_params(mock.Mock(), (("arg", "arg"),), {}),
[("arg", "arg")],
)
# /home/classic/dev/sqlalchemy/test/profiles.txt
# This file is written out on a per-environment basis.
-# For each test in aaa_profiling, the corresponding function and
+# For each test in aaa_profiling, the corresponding function and
# environment is located within this file. If it doesn't exist,
# the test is skipped.
-# If a callcount does exist, it is compared to what we received.
+# If a callcount does exist, it is compared to what we received.
# assertions are raised if the counts do not match.
-#
-# To add a new callcount test, apply the function_call_count
-# decorator and re-run the tests using the --write-profiles
+#
+# To add a new callcount test, apply the function_call_count
+# decorator and re-run the tests using the --write-profiles
# option - this file will be rewritten including the new count.
-#
+#
# TEST: test.aaa_profiling.test_compiler.CompileTest.test_insert
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_connection_execute x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 51
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_connection_execute x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 49
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_connection_execute x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 51
+test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_connection_execute x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 54
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_connection_execute x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 53
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_connection_execute x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 53
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_connection_execute x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 53
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 91
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 89
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 91
+test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 92
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 91
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 91
test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 91
test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 16
test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 16
test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 16
+test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 17
test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 17
test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 17
test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 17
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_legacy x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 13507
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_legacy x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 1458
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_legacy x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 13460
+test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_legacy x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 1547
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_legacy x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 1509
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_legacy x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 13512
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_legacy x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 1516
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_mappings x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 15512
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_mappings x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 2465
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_mappings x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 15467
+test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_mappings x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 2553
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_mappings x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 2517
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_mappings x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 15520
test.aaa_profiling.test_resultset.ResultSetTest.test_fetch_by_key_mappings x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 2524
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-0] x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 14
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-0] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 14
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-0] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 14
+test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-0] x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 23
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-0] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 15
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-0] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 15
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-0] x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 23
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-1] x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 16
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-1] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 14
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-1] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 16
+test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-1] x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 23
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-1] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 15
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-1] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 17
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-1] x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 23
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-2] x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 16
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-2] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 14
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-2] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 16
+test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-2] x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 23
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-2] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 15
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-2] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 17
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[False-2] x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 23
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[True-1] x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 19
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[True-1] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 17
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[True-1] x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 19
+test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[True-1] x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 28
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[True-1] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 18
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[True-1] x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 20
test.aaa_profiling.test_resultset.ResultSetTest.test_one_or_none[True-1] x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 28
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 6302
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 251
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 6271
+test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 263
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 256
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 6256
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 288
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_oracle_cx_oracle_dbapiunicode_nocextensions 6345
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_postgresql_psycopg2_dbapiunicode_cextensions 278
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_postgresql_psycopg2_dbapiunicode_nocextensions 6278
-test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_sqlite_pysqlite_dbapiunicode_cextensions 245
+test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_sqlite_pysqlite_dbapiunicode_cextensions 222
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_string x86_64_linux_cpython_3.8_sqlite_pysqlite_dbapiunicode_nocextensions 6245
# TEST: test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 6302
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 251
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 6271
+test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 263
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 256
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 6256
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 288
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_oracle_cx_oracle_dbapiunicode_nocextensions 6345
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_postgresql_psycopg2_dbapiunicode_cextensions 278
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_postgresql_psycopg2_dbapiunicode_nocextensions 6278
-test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_sqlite_pysqlite_dbapiunicode_cextensions 245
+test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_sqlite_pysqlite_dbapiunicode_cextensions 222
test.aaa_profiling.test_resultset.ResultSetTest.test_raw_unicode x86_64_linux_cpython_3.8_sqlite_pysqlite_dbapiunicode_nocextensions 6245
# TEST: test.aaa_profiling.test_resultset.ResultSetTest.test_string
test.aaa_profiling.test_resultset.ResultSetTest.test_string x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 6505
test.aaa_profiling.test_resultset.ResultSetTest.test_string x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 458
test.aaa_profiling.test_resultset.ResultSetTest.test_string x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 6460
+test.aaa_profiling.test_resultset.ResultSetTest.test_string x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 548
test.aaa_profiling.test_resultset.ResultSetTest.test_string x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 521
test.aaa_profiling.test_resultset.ResultSetTest.test_string x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 6521
test.aaa_profiling.test_resultset.ResultSetTest.test_string x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 528
test.aaa_profiling.test_resultset.ResultSetTest.test_unicode x86_64_linux_cpython_2.7_postgresql_psycopg2_dbapiunicode_nocextensions 6505
test.aaa_profiling.test_resultset.ResultSetTest.test_unicode x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_cextensions 458
test.aaa_profiling.test_resultset.ResultSetTest.test_unicode x86_64_linux_cpython_2.7_sqlite_pysqlite_dbapiunicode_nocextensions 6460
+test.aaa_profiling.test_resultset.ResultSetTest.test_unicode x86_64_linux_cpython_3.8_mariadb_mysqldb_dbapiunicode_cextensions 548
test.aaa_profiling.test_resultset.ResultSetTest.test_unicode x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_cextensions 521
test.aaa_profiling.test_resultset.ResultSetTest.test_unicode x86_64_linux_cpython_3.8_mssql_pyodbc_dbapiunicode_nocextensions 6521
test.aaa_profiling.test_resultset.ResultSetTest.test_unicode x86_64_linux_cpython_3.8_mysql_mysqldb_dbapiunicode_cextensions 528