summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-10-05 09:49:34 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2015-10-05 09:49:34 -0400
commit4578ab54a5b849fdb94a7032987f105b7ec117a4 (patch)
treeb120b471bfbccbd35b29a250db88af16cc58b925
parentd84dea62de3a9c83ad539a5cf2ff4be2c0685a94 (diff)
downloadsqlalchemy-4578ab54a5b849fdb94a7032987f105b7ec117a4.tar.gz
- Fixed bug in Oracle dialect where reflection of tables and other
symbols with names quoted to force all-lower-case would not be identified properly in reflection queries. The :class:`.quoted_name` construct is now applied to incoming symbol names that detect as forced into all-lower-case within the "name normalize" process. fixes #3548
-rw-r--r--doc/build/changelog/changelog_10.rst11
-rw-r--r--lib/sqlalchemy/dialects/oracle/base.py3
-rw-r--r--test/dialect/test_oracle.py26
3 files changed, 40 insertions, 0 deletions
diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst
index ef125eecf..a3b3e0092 100644
--- a/doc/build/changelog/changelog_10.rst
+++ b/doc/build/changelog/changelog_10.rst
@@ -19,6 +19,17 @@
:version: 1.0.9
.. change::
+ :tags: bug, oracle
+ :versions: 1.1.0b1
+ :tickets: 3548
+
+ Fixed bug in Oracle dialect where reflection of tables and other
+ symbols with names quoted to force all-lower-case would not be
+ identified properly in reflection queries. The :class:`.quoted_name`
+ construct is now applied to incoming symbol names that detect as
+ forced into all-lower-case within the "name normalize" process.
+
+ .. change::
:tags: feature, orm
:versions: 1.1.0b1
:pullreq: github:201
diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py
index c605bd510..2449b5a81 100644
--- a/lib/sqlalchemy/dialects/oracle/base.py
+++ b/lib/sqlalchemy/dialects/oracle/base.py
@@ -287,6 +287,7 @@ from sqlalchemy import util, sql
from sqlalchemy.engine import default, reflection
from sqlalchemy.sql import compiler, visitors, expression
from sqlalchemy.sql import operators as sql_operators
+from sqlalchemy.sql.elements import quoted_name
from sqlalchemy import types as sqltypes, schema as sa_schema
from sqlalchemy.types import VARCHAR, NVARCHAR, CHAR, \
BLOB, CLOB, TIMESTAMP, FLOAT
@@ -1032,6 +1033,8 @@ class OracleDialect(default.DefaultDialect):
if name.upper() == name and not \
self.identifier_preparer._requires_quotes(name.lower()):
return name.lower()
+ elif name.lower() == name:
+ return quoted_name(name, quote=True)
else:
return name
diff --git a/test/dialect/test_oracle.py b/test/dialect/test_oracle.py
index e080568cf..dd4a888ff 100644
--- a/test/dialect/test_oracle.py
+++ b/test/dialect/test_oracle.py
@@ -5,6 +5,7 @@ from sqlalchemy.testing import eq_
from sqlalchemy import *
from sqlalchemy import types as sqltypes, exc, schema
from sqlalchemy.sql import table, column
+from sqlalchemy.sql.elements import quoted_name
from sqlalchemy.testing import fixtures, AssertsExecutionResults, AssertsCompiledSQL
from sqlalchemy import testing
from sqlalchemy.util import u, b
@@ -1859,6 +1860,31 @@ class TableReflectionTest(fixtures.TestBase):
tbl = Table('test_compress', m2, autoload=True)
assert tbl.dialect_options['oracle']['compress'] == "OLTP"
+ @testing.provide_metadata
+ def test_reflect_lowercase_forced_tables(self):
+ metadata = self.metadata
+
+ Table(
+ quoted_name('t1', quote=True), metadata,
+ Column('id', Integer, primary_key=True),
+ )
+ Table(
+ quoted_name('t2', quote=True), metadata,
+ Column('id', Integer, primary_key=True),
+ Column('t1id', ForeignKey('t1.id'))
+ )
+ metadata.create_all()
+
+ m2 = MetaData(testing.db)
+ t2_ref = Table(quoted_name('t2', quote=True), m2, autoload=True)
+ t1_ref = m2.tables['t1']
+ assert t2_ref.c.t1id.references(t1_ref.c.id)
+
+ m3 = MetaData(testing.db)
+ m3.reflect(only=lambda name, m: name.lower() in ('t1', 't2'))
+ assert m3.tables['t2'].c.t1id.references(m3.tables['t1'].c.id)
+
+
class RoundTripIndexTest(fixtures.TestBase):
__only_on__ = 'oracle'