[Sqlalchemy-tickets] Issue #3661: Add join and outerjoin classmethods to declarative classes (zzzee
Brought to you by:
zzzeek
From: Haleemur A. <iss...@bi...> - 2016-02-24 05:43:57
|
New issue 3661: Add join and outerjoin classmethods to declarative classes https://bitbucket.org/zzzeek/sqlalchemy/issues/3661/add-join-and-outerjoin-classmethods-to Haleemur Ali: Given a database described via declarative syntax ``` #!python from sqlalchemy import select, Column, Integer, String from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) class Address(Base): __tablename__ = 'addresses' id = Column(Integer, primary_key=True) user_id = Column(Integer) street = Column(String) city = Column(String) postcode = Column(String) region = Column(String) ``` The following query written in sqlalchemy expression language is not valid: ``` #!python stmt = select( [User.name, Address.city] ).select_from(User.join(Address, User.id == Address.user_id)) ``` It raises `AttributeError: type object 'User' has no attribute 'join'`. However, the same expression written using `User.__table__` is valid, i.e. ``` #!python >>>str(User.__table__.join(Address, User.id == Address.user_id)) 'users JOIN addresses ON users.id = addresses.user_id' ``` produces the desired join expression. The `join` & `outerjoin` functions imported from `sqlalchemy.sql.expression` accept declarative classes as input and is able to produce the desired output ``` #!python >>>from sqlalchemy.sql.expression import join, outerjoin >>>str(join(User, Address, User.id == Address.user_id)) 'users JOIN addresses ON users.id = addresses.user_id' >>>str(outerjoin(User, Address, User.id == Address.user_id)) 'users LEFT OUTER JOIN addresses ON users.id = addresses.user_id' ``` In my opinion this is a simple fix to add `join` & `outerjoin` functions as `classmethods` to declarative classes through the mapper. That way both classically declared mappings and modern declarative mappings will be consistently usable in sqlalchemy expression language. I'd be happy to submit a PR for this change. |