From: Mike Bayer Date: Tue, 22 Dec 2015 17:04:45 +0000 (-0500) Subject: - An adjustment to the regular expression used to parse MySQL views, X-Git-Tag: rel_1_1_0b1~84^2~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8c54b14b5c0feee41bd9b9032f6b17b2dbd560a9;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - An adjustment to the regular expression used to parse MySQL views, such that we no longer assume the "ALGORITHM" keyword is present in the reflected view source, as some users have reported this not being present in some Amazon RDS environments. fixes #3613 --- diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index a9b72d2794..f9dfe339bb 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -18,6 +18,16 @@ .. changelog:: :version: 1.0.11 + .. change:: + :tags: bug, mysql + :versions: 1.1.0b1 + :tickets: 3613 + + An adjustment to the regular expression used to parse MySQL views, + such that we no longer assume the "ALGORITHM" keyword is present in + the reflected view source, as some users have reported this not being + present in some Amazon RDS environments. + .. change:: :tags: bug, mysql :versions: 1.1.0b1 diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 2740397afd..8830cb0c19 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -2806,7 +2806,7 @@ class MySQLDialect(default.DefaultDialect): schema, table_name)) sql = self._show_create_table(connection, None, charset, full_name=full_name) - if sql.startswith('CREATE ALGORITHM'): + if re.match(r'^CREATE (?:ALGORITHM)?.* VIEW', sql): # Adapt views to something table-like. columns = self._describe_table(connection, None, charset, full_name=full_name) diff --git a/test/dialect/mysql/test_reflection.py b/test/dialect/mysql/test_reflection.py index a288762625..b8cbea819a 100644 --- a/test/dialect/mysql/test_reflection.py +++ b/test/dialect/mysql/test_reflection.py @@ -397,6 +397,37 @@ class ReflectionTest(fixtures.TestBase, AssertsExecutionResults): finally: meta.drop_all() + @testing.provide_metadata + def test_view_reflection(self): + Table('x', self.metadata, Column('a', Integer), Column('b', String(50))) + self.metadata.create_all() + + with testing.db.connect() as conn: + conn.execute("CREATE VIEW v1 AS SELECT * FROM x") + conn.execute( + "CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM x") + conn.execute( + "CREATE ALGORITHM=UNDEFINED VIEW v3 AS SELECT * FROM x") + conn.execute( + "CREATE DEFINER=CURRENT_USER VIEW v4 AS SELECT * FROM x") + + @event.listens_for(self.metadata, "before_drop") + def cleanup(*arg, **kw): + with testing.db.connect() as conn: + for v in ['v1', 'v2', 'v3', 'v4']: + conn.execute("DROP VIEW %s" % v) + + insp = inspect(testing.db) + for v in ['v1', 'v2', 'v3', 'v4']: + eq_( + [ + (col['name'], col['type'].__class__) + for col in insp.get_columns(v) + ], + [('a', mysql.INTEGER), ('b', mysql.VARCHAR)] + ) + + @testing.exclude('mysql', '<', (5, 0, 0), 'no information_schema support') def test_system_views(self): dialect = testing.db.dialect