"""
+from collections import defaultdict
import re
import sys
import json
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):
'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):
from sqlalchemy import Column, Table, DDL, MetaData, TIMESTAMP, \
DefaultClause, String, Integer, Text, UnicodeText, SmallInteger,\
NCHAR, LargeBinary, DateTime, select, UniqueConstraint, Unicode,\
- BigInteger, Index
+ BigInteger, Index, ForeignKey
from sqlalchemy.schema import CreateIndex
from sqlalchemy import event
from sqlalchemy import sql
[{'name': 'foo_idx', 'column_names': ['x'], 'unique': False}]
)
+ @testing.provide_metadata
+ def test_case_sensitive_column_constraint_reflection(self):
+ # test for issue #4344 which works around
+ # MySQL 8.0 bug https://bugs.mysql.com/bug.php?id=88718
+
+ m1 = self.metadata
+
+ Table(
+ 'Track', m1, Column('TrackID', Integer, primary_key=True)
+ )
+ Table(
+ 'Track', m1, Column('TrackID', Integer, primary_key=True),
+ schema=testing.config.test_schema
+ )
+ Table(
+ 'PlaylistTrack', m1, Column('id', Integer, primary_key=True),
+ Column('TrackID',
+ ForeignKey('Track.TrackID', name='FK_PlaylistTrackId')),
+ Column(
+ 'TTrackID',
+ ForeignKey(
+ '%s.Track.TrackID' % (testing.config.test_schema,),
+ name='FK_PlaylistTTrackId'
+ )
+ )
+ )
+ m1.create_all()
+
+ eq_(
+ inspect(testing.db).get_foreign_keys('PlaylistTrack'),
+ [
+ {'name': 'FK_PlaylistTTrackId',
+ 'constrained_columns': ['TTrackID'],
+ 'referred_schema': testing.config.test_schema,
+ 'referred_table': 'Track',
+ 'referred_columns': ['TrackID'], 'options': {}},
+ {'name': 'FK_PlaylistTrackId',
+ 'constrained_columns': ['TrackID'],
+ 'referred_schema': None,
+ 'referred_table': 'Track',
+ 'referred_columns': ['TrackID'], 'options': {}}
+ ]
+ )
+
class RawReflectionTest(fixtures.TestBase):
__backend__ = True