r"""Create a SQL JOIN against this :class:`_query.Query` object's criterion and apply generatively, returning the newly resulting :class:`_query.Query`. **Simple Relationship Joins** Consider a mapping between two classes ``User`` and ``Address``, wi
(
self,
target: _JoinTargetArgument,
onclause: Optional[_OnClauseArgument] = None,
*,
isouter: bool = False,
full: bool = False,
)
| 2240 | @_generative |
| 2241 | @_assertions(_no_statement_condition, _no_limit_offset) |
| 2242 | def join( |
| 2243 | self, |
| 2244 | target: _JoinTargetArgument, |
| 2245 | onclause: Optional[_OnClauseArgument] = None, |
| 2246 | *, |
| 2247 | isouter: bool = False, |
| 2248 | full: bool = False, |
| 2249 | ) -> Self: |
| 2250 | r"""Create a SQL JOIN against this :class:`_query.Query` |
| 2251 | object's criterion |
| 2252 | and apply generatively, returning the newly resulting |
| 2253 | :class:`_query.Query`. |
| 2254 | |
| 2255 | **Simple Relationship Joins** |
| 2256 | |
| 2257 | Consider a mapping between two classes ``User`` and ``Address``, |
| 2258 | with a relationship ``User.addresses`` representing a collection |
| 2259 | of ``Address`` objects associated with each ``User``. The most |
| 2260 | common usage of :meth:`_query.Query.join` |
| 2261 | is to create a JOIN along this |
| 2262 | relationship, using the ``User.addresses`` attribute as an indicator |
| 2263 | for how this should occur:: |
| 2264 | |
| 2265 | q = session.query(User).join(User.addresses) |
| 2266 | |
| 2267 | Where above, the call to :meth:`_query.Query.join` along |
| 2268 | ``User.addresses`` will result in SQL approximately equivalent to: |
| 2269 | |
| 2270 | .. sourcecode:: sql |
| 2271 | |
| 2272 | SELECT user.id, user.name |
| 2273 | FROM user JOIN address ON user.id = address.user_id |
| 2274 | |
| 2275 | In the above example we refer to ``User.addresses`` as passed to |
| 2276 | :meth:`_query.Query.join` as the "on clause", that is, it indicates |
| 2277 | how the "ON" portion of the JOIN should be constructed. |
| 2278 | |
| 2279 | To construct a chain of joins, multiple :meth:`_query.Query.join` |
| 2280 | calls may be used. The relationship-bound attribute implies both |
| 2281 | the left and right side of the join at once:: |
| 2282 | |
| 2283 | q = ( |
| 2284 | session.query(User) |
| 2285 | .join(User.orders) |
| 2286 | .join(Order.items) |
| 2287 | .join(Item.keywords) |
| 2288 | ) |
| 2289 | |
| 2290 | .. note:: as seen in the above example, **the order in which each |
| 2291 | call to the join() method occurs is important**. Query would not, |
| 2292 | for example, know how to join correctly if we were to specify |
| 2293 | ``User``, then ``Item``, then ``Order``, in our chain of joins; in |
| 2294 | such a case, depending on the arguments passed, it may raise an |
| 2295 | error that it doesn't know how to join, or it may produce invalid |
| 2296 | SQL in which case the database will raise an error. In correct |
| 2297 | practice, the |
| 2298 | :meth:`_query.Query.join` method is invoked in such a way that lines |
| 2299 | up with how we would want the JOIN clauses in SQL to be |