【问题标题】:SQLAlchemy @hybrid_method and @distance.expression TypeError: float() argument must be a string or a number, not 'InstrumentedAttribute'SQLAlchemy @hybrid_method 和 @distance.expression TypeError: float() 参数必须是字符串或数字,而不是“InstrumentedAttribute”
【发布时间】:2019-03-02 07:27:43
【问题描述】:

我得到了这个模型和这个混合方法和表达式:

def gc_distance(lat1, lon1, latitude, longitude, math=math):
    import pdb; pdb.set_trace()
    dst = (3958.75 *
           math.acos(math.sin(float(lat1) / 57.2959) * math.sin(float(latitude) / 57.2960) +
                     math.cos(float(lat1) / 57.2958) * math.cos(float(latitude) / 57.2958) *
                     math.cos(longitude / 57.2958 - float(lon1)/57.2958)))
    return dst


class Job(db.Model):

    __tablename__ = "job"

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), nullable=False)
    city = db.Column(db.String(250), nullable=False)
    state = db.Column(db.String(10), nullable=False)
    zipCode = db.Column(db.String(10), nullable=False)
    latitude = db.Column(db.String(10), nullable=False)
    longitude = db.Column(db.String(10), nullable=False)
    description = db.Column(db.String(200), nullable=False)
    narrative = db.Column(db.String(250), nullable=False)
    companyLogo = db.Column(db.String(250), nullable=False)
    companyName = db.Column(db.String(250), nullable=False)
    companyURL = db.Column(db.String(100), nullable=False)
    time_created = db.Column(db.DateTime, nullable=False)

    @hybrid_method
    def distance(self, lat, lng):
        import pdb; pdb.set_trace()
        return gc_distance(lat, lng, self.latitude, self.longitude)

    @distance.expression
    def distance(cls, lat, lng):
        import pdb; pdb.set_trace()
        return gc_distance(lat, lng, cls.latitude, cls.longitude, math=func)

我正在调用我的方法:

@classmethod
def getJobsWithinXMiles(cls, lat1: str, lon1: str, dst: str,
                            page: int, per_page: int)-> "JobModel":

             stmt = db.session.query(
                        Job,
                        Job.distance(lat1, lon1).
                        label('distance')).\
                    subquery()


              job_alias = aliased(Job, stmt)

              jobs = db.session.query(job_alias).\
                    filter(stmt.c.distance < dst).\
                    order_by(stmt.c.distance).\
                    paginate(page, per_page).\
                    params(lat1=float(lat1),
                           lon1=float(lon1),
                           dst=int(dst),
                           page=int(page),
                           per_page=int(per_page)
                           )
                return jobs

现在当我从我的角度调用这个方法时,我得到了这个错误:

第 27 行,在 gc_distance 中 dst = (3958.75 * TypeError: float() 参数必须是字符串或数字,而不是 'InstrumentedAttribute'

错误在函数 gc_distance(lat1, lon1, latitude, longitude, math=math) 中。我看到纬度是“InstrumentedAttribute”类型的,这就是产生错误的原因

有人可以帮忙找出这个错误的原因吗?

【问题讨论】:

  • 由于您没有使用原始/文本 SQL,因此不需要 params() 调用。
  • 我删除了 params() 。现在一切正常。谢谢伊利亚

标签: python postgresql sqlalchemy psycopg2


【解决方案1】:

函数gc_distance() 尝试将latitude 转换为float,尽管它也用作SQL 表达式中的列元素参数。您应该将转换移动到相应的混合体:

@hybrid_method
def distance(self, lat, lng):
    return gc_distance(lat, lng, float(self.latitude), float(self.longitude))

@distance.expression
def distance(cls, lat, lng):
    return gc_distance(lat, lng, cls.latitude.cast(db.Float), cls.longitude.cast(db.Float), math=func)

然后用latitude 代替float(latitude)。长期的解决方案是将latitudelongitude 列的数据类型固定为合适的数字类型。

【讨论】:

  • 一如既往你是对的。它工作得很好,只是我的分页不起作用。但是如果不使用分页,它就可以完美地工作。我将在分页部分工作,看看可能出了什么问题。在我关闭此问题并接受您的回复之前,我必须通过将 c 添加到 stmp.c.distance 而不是 stmp.distance 来修改代码。这个 c 的真正含义是什么?为什么有必要?
  • 分页在我看来是个问题。您的解决方案非常完美。谢谢
  • 我试图以另一种方式解决这个问题。现在它已经解决了。但是我想知道为什么我之前的尝试没有奏效?可以看看我在这里问的这个问题link
猜你喜欢
  • 2023-02-18
  • 2020-04-24
  • 1970-01-01
  • 2021-03-30
  • 2018-02-26
  • 2022-08-13
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多