SQLAlchemy @hybrid_method и @ distance.expression TypeError: аргумент float () должен быть строкой или числом, а не «InstrumentedAttribute» - PullRequest
0 голосов
/ 02 марта 2019

Я получил эту модель, этот гибридный метод и выражение:

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

Теперь, когда я вызываю этот метод из моегоview Я получил эту ошибку:

строка 27, в gc_distance dst = (3958.75 * TypeError: аргумент float () должен быть строкой или числом, а не 'InstrumentedAttribute'

Ошибка в функции gc_distance (lat1, lon1, широта, долгота, математика = математика). Я вижу, что широта имеет тип «InstrumentedAttribute» и именно она генерирует ошибку

Может кто-нибудь помочьв поиске причины этой ошибки?

1 Ответ

0 голосов
/ 02 марта 2019

Функция 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)

, а затем вместо float(latitude) просто использовать latitude.Долгосрочным решением было бы установить тип данных столбцов latitude и longitude для подходящего числового типа.

...