mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-29 20:14:55 -04:00
a5ede47f12
labeled columns when apply_labels() is used; this mode produces a SELECT where each column is labeled as in <tablename>_<columnname>, to remove column name collisions for a multiple table select. The fix is that if two labels collide when combined with the table name, i.e. "foo.bar_id" and "foo_bar.id", anonymous aliasing will be applied to one of the dupes. This allows the ORM to handle both columns independently; previously, 0.7 would in some cases silently emit a second SELECT for the column that was "duped", and in 0.8 an ambiguous column error would be emitted. The "keys" applied to the .c. collection of the select() will also be deduped, so that the "column being replaced" warning will no longer emit for any select() that specifies use_labels, though the dupe key will be given an anonymous label which isn't generally user-friendly. [ticket:2702]
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
from sqlalchemy import *
|
|
from sqlalchemy.testing import *
|
|
from sqlalchemy.engine import default
|
|
|
|
class CompileTest(fixtures.TestBase, AssertsExecutionResults):
|
|
__requires__ = 'cpython',
|
|
|
|
@classmethod
|
|
def setup_class(cls):
|
|
|
|
global t1, t2, metadata
|
|
metadata = MetaData()
|
|
t1 = Table('t1', metadata,
|
|
Column('c1', Integer, primary_key=True),
|
|
Column('c2', String(30)))
|
|
|
|
t2 = Table('t2', metadata,
|
|
Column('c1', Integer, primary_key=True),
|
|
Column('c2', String(30)))
|
|
|
|
# do a "compile" ahead of time to load
|
|
# deferred imports
|
|
t1.insert().compile()
|
|
|
|
# go through all the TypeEngine
|
|
# objects in use and pre-load their _type_affinity
|
|
# entries.
|
|
for t in (t1, t2):
|
|
for c in t.c:
|
|
c.type._type_affinity
|
|
from sqlalchemy import types
|
|
for t in types._type_map.values():
|
|
t._type_affinity
|
|
|
|
cls.dialect = default.DefaultDialect()
|
|
|
|
@profiling.function_call_count()
|
|
def test_insert(self):
|
|
t1.insert().compile(dialect=self.dialect)
|
|
|
|
@profiling.function_call_count()
|
|
def test_update(self):
|
|
t1.update().compile(dialect=self.dialect)
|
|
|
|
def test_update_whereclause(self):
|
|
t1.update().where(t1.c.c2 == 12).compile(dialect=self.dialect)
|
|
|
|
@profiling.function_call_count()
|
|
def go():
|
|
t1.update().where(t1.c.c2 == 12).compile(dialect=self.dialect)
|
|
go()
|
|
|
|
def test_select(self):
|
|
# give some of the cached type values
|
|
# a chance to warm up
|
|
s = select([t1], t1.c.c2 == t2.c.c1)
|
|
s.compile(dialect=self.dialect)
|
|
|
|
@profiling.function_call_count()
|
|
def go():
|
|
s = select([t1], t1.c.c2 == t2.c.c1)
|
|
s.compile(dialect=self.dialect)
|
|
go()
|
|
|
|
def test_select_labels(self):
|
|
# give some of the cached type values
|
|
# a chance to warm up
|
|
s = select([t1], t1.c.c2 == t2.c.c1).apply_labels()
|
|
s.compile(dialect=self.dialect)
|
|
|
|
@profiling.function_call_count()
|
|
def go():
|
|
s = select([t1], t1.c.c2 == t2.c.c1).apply_labels()
|
|
s.compile(dialect=self.dialect)
|
|
go() |