Home > Software design >  sqlalchemy join returns results from first table only
sqlalchemy join returns results from first table only

Time:12-09

so this is my issue, I have the following tables:

class ClientCampaings(Base):

__tablename__ = 'client_campaign'

campaign_id = Column(INTEGER, primary_key=True)
client_id = Column(VARCHAR(50))
campaign_name = Column(VARCHAR(45))
campaign_status = Column(VARCHAR(45))
campaign_type = Column(VARCHAR(45))
registration_date = Column(DATE)


class ClientKpi(Base):

__tablename__ = 'client_kpi'

kpi_id = Column(INTEGER, primary_key=True)
kpi_name = Column(VARCHAR(45))
cost_conv = Column(FLOAT)
quality_score = Column(FLOAT)



class KpiAssigment(Base):

__tablename__ = 'kpi_assigment'

assigment_id = Column(INTEGER, primary_key=True)
kpi_id = Column(INTEGER, ForeignKey("client_kpi.kpi_id"))
campaign_id = Column(INTEGER, ForeignKey("client_campaign.campaign_id"))
assigned_by = Column(VARCHAR(45))
timestamp = Column(TIMESTAMP)

#Basic One To Many relation
client_campaign = relationship("ClientCampaings")
client_kpi = relationship("ClientKpi")

Them I do the following query:

from database.session import MySqlConnection
from database.models import KpiAssigment,ClientKpi

db = MySqlConnection(database='db_goes_here').db_session()

kpi=db.query(KpiAssigment)\
      .join(ClientKpi)\
      .filter(KpiAssigment.kpi_id==ClientKpi.kpi_id).all()

Which I thought was going to be something like this:

SELECT kpi_assigment.*,
       client_kpi.*
FROM kpi_assigment
INNER JOIN client_kpi
ON kpi_assigment.kpi_id=client_kpi.kpi_id

However, when I run the SqlAlchemy query I getting back only the results from the first table:

 {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7fb3d0ace910>, 'kpi_id': 1, 'assigned_by': '[email protected]', 'assigment_id': 2, 'campaign_id': XXXXXXXXX, 'timestamp': datetime.datetime(2022, 12, 7, 17, 5, 8)}

I was looking to get an INNER JOIN and have also the data from ClientKpi table.

I read these related issues but still not finding why this isn't working

SqlAlchemy Outer Join Only Returns One Table

How to join data from two tables in SQLAlchemy?

and I did follow their documentation

https://docs.sqlalchemy.org/en/14/orm/query.html#sqlalchemy.orm.Query.join

Any thoughts?

Thanks

CodePudding user response:

The query

kpi=db.query(KpiAssigment)\
      .join(ClientKpi)\
      .filter(KpiAssigment.kpi_id==ClientKpi.kpi_id).all()

will only select the KpiAssignemnt table; to select the corresponding ClientKpi(s) include the ClientKpi model in the query:

kpi=db.query(KpiAssigment, ClientKpi).join(ClientKpi)

The .filter is redundant as SQLAlchemy will use the declared foreign keys to create the JOIN.

If you want to loop over the child objects for each parent you can use the relationship without an explicit join:

for client_kpi in some_kpi_assignment.client_kpi:
    # do something

CodePudding user response:

Still trying to find out if there is a better response for this, in the meantime, I did the following and got what I was looking for:

 query = db.query(KpiAssigment.campaign_id, 
                  ClientKpi.cost_conv,
                  ClientKpi.quality_score)\
                  .join(ClientKpi)\
                  .filter(KpiAssigment.kpi_id==ClientKpi.kpi_id)\
                  .all()

Which returns the resulta has a list of tuples:

print(query)

>>>[(1, 6.0, 2), (2, 6.0, 2)]
  • Related