Add Executable to DefaultGenerator

Fixed the class hierarchy for the :class:`_schema.Sequence` and the more
general :class:`_schema.DefaultGenerator` base, as these are "executable"
as statements they need to include :class:`_sql.Executable` in their
hierarchy, not just :class:`_roles.StatementRole` as was applied
arbitrarily to :class:`_schema.Sequence` previously. The fix allows
:class:`_schema.Sequence` to work in all ``.execute()`` methods including
with :meth:`_orm.Session.execute` which was not working in the case that a
``do_orm_execute()`` handler was also established.

Fixes: #6668
Change-Id: I0d192258c7cbd1bce2552f9e748e8fdd680dc45f
This commit is contained in:
Mike Bayer
2021-06-23 16:34:05 -04:00
parent 2f875a4b79
commit 80b90cbcfe
4 changed files with 35 additions and 11 deletions
+13
View File
@@ -0,0 +1,13 @@
.. change::
:tags: bug, sql, orm
:tickets: 6668
Fixed the class hierarchy for the :class:`_schema.Sequence` and the more
general :class:`_schema.DefaultGenerator` base, as these are "executable"
as statements they need to include :class:`_sql.Executable` in their
hierarchy, not just :class:`_roles.StatementRole` as was applied
arbitrarily to :class:`_schema.Sequence` previously. The fix allows
:class:`_schema.Sequence` to work in all ``.execute()`` methods including
with :meth:`_orm.Session.execute` which was not working in the case that a
``do_orm_execute()`` handler was also established.
+1 -1
View File
@@ -1835,7 +1835,7 @@ class Connection(Connectable):
if self._echo:
self._log_info(statement)
self._log_info("%r", parameters)
self._log_info("[raw sql] %r", parameters)
try:
for fn in (
()
+3 -2
View File
@@ -41,6 +41,7 @@ from . import visitors
from .base import _bind_or_error
from .base import DedupeColumnCollection
from .base import DialectKWArgs
from .base import Executable
from .base import SchemaEventTarget
from .coercions import _document_text_coercion
from .elements import ClauseElement
@@ -2464,7 +2465,7 @@ class ForeignKey(DialectKWArgs, SchemaItem):
self._set_target_column(_column)
class DefaultGenerator(SchemaItem):
class DefaultGenerator(Executable, SchemaItem):
"""Base class for column *default* values."""
__visit_name__ = "default_generator"
@@ -2678,7 +2679,7 @@ class IdentityOptions(object):
self.order = order
class Sequence(IdentityOptions, roles.StatementRole, DefaultGenerator):
class Sequence(IdentityOptions, DefaultGenerator):
"""Represents a named database sequence.
The :class:`.Sequence` object represents the name and configurational
+18 -8
View File
@@ -48,15 +48,25 @@ class ExecutionTest(_fixtures.FixtureTest):
run_inserts = None
__backend__ = True
@testing.combinations(
(True,), (False,), argnames="add_do_orm_execute_event"
)
@testing.requires.sequences
def test_sequence_execute(self, connection):
seq = Sequence("some_sequence")
seq.create(connection)
try:
sess = Session(connection)
eq_(sess.execute(seq), connection.dialect.default_sequence_base)
finally:
seq.drop(connection)
def test_sequence_execute(
self, connection, metadata, add_do_orm_execute_event
):
seq = Sequence("some_sequence", metadata=metadata)
metadata.create_all(connection)
sess = Session(connection)
if add_do_orm_execute_event:
evt = mock.Mock(return_value=None)
event.listen(
sess, "do_orm_execute", lambda ctx: evt(ctx.statement)
)
eq_(sess.execute(seq), connection.dialect.default_sequence_base)
if add_do_orm_execute_event:
eq_(evt.mock_calls, [mock.call(seq)])
def test_parameter_execute(self):
users = self.tables.users