Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering after a join in Flask-SQLAlchemy

I have two tables( location and country ) that am trying to query; which are represented by the models below in my flask application

from sqlalchemy import Column, DateTime, ForeignKey, Integer, \
                       Numeric, SmallInteger, String, Table
from sqlalchemy.orm import relationship
from sqlalchemy.schema import FetchedValue
from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()


class Country(db.Model):
    __tablename__ = 'country'

    country_id = db.Column(db.Integer, primary_key=True)
    country_name = db.Column(db.String(30), nullable=False)
    full_country_name = db.Column(db.String(90), nullable=False)
    country_code = db.Column(db.String(4), nullable=False)

    def __str__(self):
        return '%s' % self.country_name

    def __repr__(self):
        return '<Country %r>' % self.country_name


class Location(db.Model):
    __tablename__ = 'location'

    location_id = db.Column(db.Integer, primary_key=True)
    location_name = db.Column(db.String(75), nullable=False)
    country_id = db.Column(db.ForeignKey('mashamba.country.country_id'), nullable=False, index=True)

    country = db.relationship('Country', primaryjoin='Location.country_id == Country.country_id', backref='locations')

    def __str__(self):
        return '%s' % self.location_name

    def __repr__(self):
        return '<Location %r>' % self.location_name

What am trying to do is get all columns from both tables by performing a join using the following code

Location.query.join(Country).\
                filter_by(location_name='Cairo',
                          country_id=67).first()

Problem is when i run the code i get the following error

sqlalchemy.exc.InvalidRequestError: Entity '<class 'app.models.Country'>' has no property 'location_name'

Everything works fine when you run for example this code

Location.query.join(Country).all()

What is wrong here and how can this be solved?

like image 643
kellymandem Avatar asked Aug 15 '18 16:08

kellymandem


1 Answers

filter_by() applies to the primary entity of the query, or the last entity that was the target of a join(). In your case that is Country, which does not have the required attribute. Either use filter() or move the call to filter_by(location_name=...) before the join:

Location.query.\
    filter_by(location_name='Cairo').\
    join(Country).\
    filter_by(country_id=67).\
    first()
like image 79
Ilja Everilä Avatar answered Oct 01 '22 20:10

Ilja Everilä