In Oracle, the data dictionary represents all case insensitive identifier names using UPPERCASE text. SQLAlchemy on the other hand considers an all-lower case identifier name to be case insensitive. The Oracle dialect converts all case insensitive identifiers to and from those two formats during schema level communication, such as reflection of tables and indexes. Using an UPPERCASE name on the SQLAlchemy side indicates a case sensitive identifier, and SQLAlchemy will quote the name - this will cause mismatches against data dictionary data received from Oracle, so unless identifier names have been truly created as case sensitive (i.e. using quoted names), all lowercase names should be used on the SQLAlchemy side.
if name_upper == name_lower: # name has no upper/lower conversion, e.g. non-european characters. # return unchanged return name elif name_upper == name andnot ( self.identifier_preparer._requires_quotes )(name_lower): # name is all uppercase and doesn't require quoting; normalize # to all lower case return name_lower elif name_lower == name: # name is all lower case, which if denormalized means we need to # force quoting on it return quoted_name(name, quote=True) else: # name is mixed case, means it will be quoted in SQL when used # later, no normalizes return name
defdenormalize_name(self, name): if name isNone: returnNone
if name_upper == name_lower: # name has no upper/lower conversion, e.g. non-european characters. # return unchanged return name elif name_lower == name andnot ( self.identifier_preparer._requires_quotes )(name_lower): name = name_upper return name
def_requires_quotes(self, value): """Return True if the given identifier requires quoting.""" lc_value = value.lower() uc_value = value.upper() return ( lc_value in self.reserved_words or value[0] in self.illegal_initial_characters ornot self.legal_characters.match(util.text_type(value)) or ((lc_value != value) and (uc_value != value)) # change here, allow all uppercaes )