summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-10-02 17:49:44 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-10-03 09:52:38 -0400
commit56fb68ca8620a211ca29b3d47d649dfa332d354a (patch)
tree17c5c88c4725056116e71a3efabedb4ff5301497 /lib/sqlalchemy
parentffd27cef48241e39725c4e9cd13fd744a2806bdd (diff)
downloadsqlalchemy-56fb68ca8620a211ca29b3d47d649dfa332d354a.tar.gz
Perform additional retrieval of correct column names
Added a workaround for a MySQL bug #88718 introduced in the 8.0 series, where the reflection of a foreign key constraint is not reporting the correct case sensitivity for the referred column, leading to errors during use of the reflected constraint such as when using the automap extension. The workaround emits an additional query to the information_schema tables in order to retrieve the correct case sensitive name. Fixes: #4344 Change-Id: I08020d6eec43cbe8a56316660380d3739a0b45f7
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index 45e8c2510..cd17bcdc4 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -733,6 +733,7 @@ output::
"""
+from collections import defaultdict
import re
import sys
import json
@@ -1979,6 +1980,10 @@ class MySQLDialect(default.DefaultDialect):
default.DefaultDialect.initialize(self, connection)
+ self._needs_correct_for_88718 = (
+ not self._is_mariadb and self.server_version_info >= (8, )
+ )
+
self._warn_for_known_db_issues()
def _warn_for_known_db_issues(self):
@@ -2130,8 +2135,56 @@ class MySQLDialect(default.DefaultDialect):
'options': con_kw
}
fkeys.append(fkey_d)
+
+ if self._needs_correct_for_88718:
+ self._correct_for_mysql_bug_88718(fkeys, connection)
+
return fkeys
+ def _correct_for_mysql_bug_88718(self, fkeys, connection):
+ # Foreign key is always in lower case (MySQL 8.0)
+ # https://bugs.mysql.com/bug.php?id=88718
+ # issue #4344 for SQLAlchemy
+
+ default_schema_name = connection.dialect.default_schema_name
+ col_tuples = [
+ (
+ rec['referred_schema'] or default_schema_name,
+ rec['referred_table'],
+ col_name
+ )
+ for rec in fkeys
+ for col_name in rec['referred_columns']
+ ]
+
+ if col_tuples:
+
+ correct_for_wrong_fk_case = connection.execute(
+ sql.text("""
+ select table_schema, table_name, column_name
+ from information_schema.columns
+ where (table_schema, table_name, lower(column_name)) in
+ :table_data;
+ """).bindparams(
+ sql.bindparam("table_data", expanding=True)
+ ), table_data=col_tuples
+ )
+
+ d = defaultdict(dict)
+ for schema, tname, cname in correct_for_wrong_fk_case:
+ d[(schema, tname)][cname.lower()] = cname
+
+ for fkey in fkeys:
+ fkey['referred_columns'] = [
+ d[
+ (
+ fkey['referred_schema'] or default_schema_name,
+ fkey['referred_table']
+ )
+ ][col.lower()]
+ for col in fkey['referred_columns']
+ ]
+
@reflection.cache
def get_check_constraints(
self, connection, table_name, schema=None, **kw):