same target more than once; it implicitly dedupes only in the case of
a relationship join, and due to 🎫`3233`, in 1.0 a join
to the same table twice behaves differently than 0.9 in that it no
longer erroneously aliases. To help document this change,
the verbiage regarding 🎫`3233` in the migration notes has
been generalized, and a warning has been added when :meth:`.Query.join`
is called against the same target relationship more than once.
fixes#3367
ultimately will populate a foreign key column in conflict with
another, where the relationships are attempting to copy values
from different source columns. This occurs in the case where
composite foreign keys with overlapping columns are mapped to
relationships that each refer to a different referenced column.
A new documentation section illustrates the example as well as how
to overcome the issue by specifying "foreign" columns specifically
on a per-relationship basis.
fixes#3230
$ python setup.py develop
$ pip install nose
$ pip install mock
$ ./sqla_nose.py test.orm.test_joins
.....................................................................................................
----------------------------------------------------------------------
Ran 101 tests in 1.222s
OK
$ ./sqla_nose.py test.orm
......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................S......................................................................................................................................................................................................................................................................................................................S.......................................................................................................................................................................................................................................................................................................................................................S.......S..S.SSS.SS...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................S................................S..S........................S...........................................................................................SSS.S.........SSSSSSSS......SSSSSSSSS........SS...SS...............S.............................S..............................................................SS..SS..............................................................................................................S.
----------------------------------------------------------------------
Ran 3103 tests in 82.607s
OK (SKIP=46)
against a non-selectable, such as a :func:`.literal_column`, and then
an attempt was made to use :meth:`.Query.join` such that the "left"
side would be determined as ``None`` and then fail. This condition
is now detected explicitly.
target of :paramref:`.relationship.secondary` for the purposes
of creating very complex :func:`.relationship` join conditions.
The change includes adjustments to query joining, joined eager loading
to not render a SELECT subquery, changes to lazy loading such that
the "secondary" target is properly included in the SELECT, and
changes to declarative to better support specification of a
join() object with classes as targets.
alias when saying query(B).join(B.cs), where "C" is a joined inh
class; however, this implicit alias was created only considering
the immediate left side, and not a longer chain of joins along different
joined-inh subclasses of the same base. As long as we're still
implicitly aliasing in this case, the behavior is dialed back a bit
so that it will alias the right side in a wider variety of cases.
[ticket:2903]
- paths now store Mapper + MapperProperty now instead of string key,
so that the parent mapper for the property is known, supports same-named
properties on multiple subclasses
- the Mapper within the path is now always relevant to the property
to the right of it. PathRegistry does the translation now, instead
of having all the outside users of PathRegistry worry about it,
to produce a path that is much more consistent. Paths are now
consistent with mappings in all cases. Special logic to get at
"with_polymorphic" structures and such added also.
- AliasedClass now has two modes, "use_mapper_path" and regular;
"use_mapper_path" is for all those situations where we put an AliasedClass
in for a plain class internally, and want it to "path" with the
plain mapper.
- The AliasedInsp is now the first class "entity" for an AliasedClass,
and is passed around internally and used as attr._parententity
and such. it is the AliasedClass analogue for Mapper.
become an externally usable package but still remains within the main sqlalchemy parent package.
in this system, we use kind of an ugly hack to get the noseplugin imported outside of the
"sqlalchemy" package, while still making it available within sqlalchemy for usage by
third party libraries.
can more flexibly be a non-ORM selectable,
such as a subquery. A selectable placed
in select_from() will now be used as the left
side, favored over implicit usage
of a mapped entity.
If the join still fails based on lack of
foreign keys, the error message includes
this detail. Thanks to brianrhude
on IRC for the test case. [ticket:2298]
from 0.6:
- making a synonym against a synonym now works.
- synonyms made against a relationship() can
be passed to query.join(), options sent
to query.options(), passed by name
to query.with_parent().
- revised the approach taken earlier to just
propagate "property" out from the proxied attr the same
way queryable attribute does.
in a complex multiple-overlapping path scenario,
where the same table could be joined to
twice. Thanks *much* to Dave Vitek
for the excellent fix here. [ticket:2247]
recursive descent with clone() + _copy_internals(). This is essentially
what it was doing anyway with lots of unnecessary steps.
Fix Alias() to honor the given clone() function which may have been the
reason the traversal hadn't been fixed sooner. Alias._copy_internals()
will specifically skip an alias of a Table
as a more specific form of what it was doing before. This may need to
be further improved such that ClauseAdapter or replacement_traverse()
send it some specific hints what not to dig into; **kw has been added
to all _copy_internals() to support this. replacement/clone traversal
is at least clear now.
- apply new no_replacement_traverse annotation to join created by
_create_joins(), fixes [ticket:2195]
- can replace orm.query "_halt_adapt" with "no_replacement_traverse"
all referncing tests to not use globals
- tests that deal with pickle specifically load the fixture classes
from test.lib.pickleable, which gets some more classes added
- removed weird sa05 pickling tests that don't matter
access to the cls/self.tables/classes registries
- express orm/_base.py ORMTest in terms of engine/_base.py TablesTest,
factor out common steps into TablesTest, remove AltEngineTest as a
separate class. will further consolidate these base classes