【问题标题】:Filtering after a join in Flask-SQLAlchemy在 Flask-SQLAlchemy 中加入后过滤
【发布时间】:2018-08-15 16:21:04
【问题描述】:

我有两个表(locationcountry)正在尝试查询;在我的烧瓶应用程序中由以下模型表示

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

我要做的是通过使用以下代码执行连接来获取两个表中的所有列

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

问题是当我运行代码时出现以下错误

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

运行此代码时一切正常

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

这里出了什么问题,如何解决?

【问题讨论】:

  • 我手头没有 Flask-SQLAlchemy,但我认为你需要在这里切换到 filter 而不是 filter_by 以便区分,例如:filter(Location.location_name == 'Cairo', Country.country_id == 67)
  • 旁注:将名称范围加倍是不寻常的。只写Location.id 而不是Location.location_id
  • @Two-Bit Alchemist 谢谢你的效果很好
  • @Two-BitAlchemist “双重作用域”实际上是一种非常方便的做法。它通常允许在连接中使用USING,如果必须编写原始SQL,甚至可以使用NATURAL JOIN。如果不使用虚线标识符或使用生成的别名,识别大型查询中的内容也容易得多。它在 Python 中也有帮助:如果您将错误类型的对象传递给函数,它会在尝试访问例如 location_id 时提前崩溃。如果所有 DB 对象都共享 id 作为主键,那么您可能不会更聪明。

标签: python flask sqlalchemy flask-sqlalchemy


【解决方案1】:

filter_by() 适用于查询的主要实体,或作为join() 目标的最后一个实体。在您的情况下是Country,它没有必需的属性。在加入前使用filter() 或将呼叫移至filter_by(location_name=...)

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

【讨论】:

  • 谢谢你,我测试了你的代码,它也可以正常工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 2015-03-01
  • 1970-01-01
  • 2016-05-08
相关资源
最近更新 更多