full revision.
"""
+
if isinstance(id_, (list, tuple, set, frozenset)):
return sum([self.get_revisions(id_elem) for id_elem in id_], ())
else:
def _resolve_revision_number(self, id_):
if isinstance(id_, compat.string_types) and "@" in id_:
branch_label, id_ = id_.split("@", 1)
+
+ elif id_ is not None and (
+ (
+ isinstance(id_, tuple)
+ and id_
+ and not isinstance(id_[0], compat.string_types)
+ )
+ or not isinstance(id_, compat.string_types + (tuple, ))
+ ):
+ raise RevisionError(
+ "revision identifier %r is not a string; ensure database "
+ "driver settings are correct" % (id_,)
+ )
+
else:
branch_label = None
+import sys
+
from alembic import util
from alembic.util import sqla_compat
from . import exclusions
"SQLAlchemy 1.2.16, 1.3.0b2 or greater required",
)
+ @property
+ def python3(self):
+ return exclusions.skip_if(
+ lambda: sys.version_info < (3,), "Python version 3.xx is required."
+ )
+
@property
def pep3147(self):
--- /dev/null
+.. change::
+ :tags: bug, operations, mysql
+ :tickets: 551
+
+ Added an assertion in :meth:`.RevisionMap.get_revisions` and other methods
+ which ensures revision numbers are passed as strings or collections of
+ strings. Driver issues particularly on MySQL may inadvertently be passing
+ bytes here which leads to failures later on.
\ No newline at end of file
from alembic.script.revision import RevisionError
from alembic.script.revision import RevisionMap
from alembic.testing import assert_raises_message
+from alembic.testing import config
from alembic.testing import eq_
from alembic.testing.fixtures import TestBase
from . import _large_map
class APITest(TestBase):
+ @config.requirements.python3
+ def test_invalid_datatype(self):
+ map_ = RevisionMap(
+ lambda: [
+ Revision("a", ()),
+ Revision("b", ("a",)),
+ Revision("c", ("b",)),
+ ]
+ )
+ assert_raises_message(
+ RevisionError,
+ "revision identifier b'12345' is not a string; "
+ "ensure database driver settings are correct",
+ map_.get_revisions, b'12345'
+ )
+
+ assert_raises_message(
+ RevisionError,
+ "revision identifier b'12345' is not a string; "
+ "ensure database driver settings are correct",
+ map_.get_revision, b'12345'
+ )
+
+ assert_raises_message(
+ RevisionError,
+ r"revision identifier \(b'12345',\) is not a string; "
+ "ensure database driver settings are correct",
+ map_.get_revision, (b'12345', )
+ )
+
+ map_.get_revision(("a", ))
+ map_.get_revision("a")
+
def test_add_revision_one_head(self):
map_ = RevisionMap(
lambda: [