diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-06-28 14:33:14 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-06-28 14:34:51 -0400 |
| commit | 9d2dc7911b7767b97814479d228072b6f566a864 (patch) | |
| tree | c532a3ff7ccd97bf7aa887ae2c4ca5c0991ad04c | |
| parent | 6ad882c861403dc7e21ec84eec5f707fe3ffdc7b (diff) | |
| download | sqlalchemy-9d2dc7911b7767b97814479d228072b6f566a864.tar.gz | |
Reflect ASC/DESC in MySQL index columns
Fixed bug in index reflection where on MySQL 8.0 an index that includes
ASC or DESC in an indexed column specfication would not be correctly
reflected, as MySQL 8.0 introduces support for returning this information
in a table definition string.
Change-Id: I21f64984ade690aac8c87dbe3aad0c1ee8e9727f
Fixes: #4293
| -rw-r--r-- | doc/build/changelog/unreleased_12/4293.rst | 8 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/mysql/reflection.py | 5 | ||||
| -rw-r--r-- | test/dialect/mysql/test_reflection.py | 63 |
3 files changed, 74 insertions, 2 deletions
diff --git a/doc/build/changelog/unreleased_12/4293.rst b/doc/build/changelog/unreleased_12/4293.rst new file mode 100644 index 000000000..51fac2033 --- /dev/null +++ b/doc/build/changelog/unreleased_12/4293.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, mysql + :tickets: 4293 + + Fixed bug in index reflection where on MySQL 8.0 an index that includes + ASC or DESC in an indexed column specfication would not be correctly + reflected, as MySQL 8.0 introduces support for returning this information + in a table definition string. diff --git a/lib/sqlalchemy/dialects/mysql/reflection.py b/lib/sqlalchemy/dialects/mysql/reflection.py index e15211044..e88bc3f42 100644 --- a/lib/sqlalchemy/dialects/mysql/reflection.py +++ b/lib/sqlalchemy/dialects/mysql/reflection.py @@ -76,6 +76,8 @@ class MySQLTableDefinitionParser(object): if m: spec = m.groupdict() # convert columns into name, length pairs + # NOTE: we may want to consider SHOW INDEX as the + # format of indexes in MySQL becomes more complex spec['columns'] = self._parse_keyexprs(spec['columns']) if spec['version_sql']: m2 = self._re_key_version_sql.match(spec['version_sql']) @@ -317,11 +319,10 @@ class MySQLTableDefinitionParser(object): # `col`,`col2`(32),`col3`(15) DESC # - # Note: ASC and DESC aren't reflected, so we'll punt... self._re_keyexprs = _re_compile( r'(?:' r'(?:%(iq)s((?:%(esc_fq)s|[^%(fq)s])+)%(fq)s)' - r'(?:\((\d+)\))?(?=\,|$))+' % quotes) + r'(?:\((\d+)\))?(?: +(ASC|DESC))?(?=\,|$))+' % quotes) # 'foo' or 'foo','bar' or 'fo,o','ba''a''r' self._re_csv_str = _re_compile(r'\x27(?:\x27\x27|[^\x27])*\x27') diff --git a/test/dialect/mysql/test_reflection.py b/test/dialect/mysql/test_reflection.py index 76b6954ae..c244ba972 100644 --- a/test/dialect/mysql/test_reflection.py +++ b/test/dialect/mysql/test_reflection.py @@ -633,6 +633,20 @@ class ReflectionTest(fixtures.TestBase, AssertsCompiledSQL): "(textdata) WITH PARSER ngram" ) + @testing.provide_metadata + def test_non_column_index(self): + m1 = self.metadata + t1 = Table( + 'add_ix', m1, Column('x', String(50)), mysql_engine='InnoDB') + Index('foo_idx', t1.c.x.desc()) + m1.create_all() + + insp = inspect(testing.db) + eq_( + insp.get_indexes("add_ix"), + [{'name': 'foo_idx', 'column_names': ['x'], 'unique': False}] + ) + class RawReflectionTest(fixtures.TestBase): __backend__ = True @@ -678,6 +692,55 @@ class RawReflectionTest(fixtures.TestBase): "/*!50100 WITH PARSER `ngram` */ " ) + def test_key_reflection_columns(self): + regex = self.parser._re_key + exprs = self.parser._re_keyexprs + m = regex.match( + " KEY (`id`) USING BTREE COMMENT '''comment'") + eq_(m.group("columns"), '`id`') + + m = regex.match( + " KEY (`x`, `y`) USING BTREE") + eq_(m.group("columns"), '`x`, `y`') + + eq_( + exprs.findall(m.group("columns")), + [("x", "", ""), ("y", "", "")] + ) + + m = regex.match( + " KEY (`x`(25), `y`(15)) USING BTREE") + eq_(m.group("columns"), '`x`(25), `y`(15)') + eq_( + exprs.findall(m.group("columns")), + [("x", "25", ""), ("y", "15", "")] + ) + + m = regex.match( + " KEY (`x`(25) DESC, `y`(15) ASC) USING BTREE") + eq_(m.group("columns"), '`x`(25) DESC, `y`(15) ASC') + eq_( + exprs.findall(m.group("columns")), + [("x", "25", "DESC"), ("y", "15", "ASC")] + ) + + m = regex.match( + " KEY `foo_idx` (`x` DESC)") + eq_(m.group("columns"), '`x` DESC') + eq_( + exprs.findall(m.group("columns")), + [("x", "", "DESC")] + ) + + eq_( + exprs.findall(m.group("columns")), + [("x", "", "DESC")] + ) + + m = regex.match( + " KEY `foo_idx` (`x` DESC, `y` ASC)") + eq_(m.group("columns"), '`x` DESC, `y` ASC') + def test_fk_reflection(self): regex = self.parser._re_fk_constraint |
