Как выполнять математические функции SQL в SQLalchemy - PullRequest
0 голосов
/ 05 ноября 2018

Я не уверен, что это невозможно, или я что-то упустил, но у меня есть сервер Flask с Flask-SQLalchemy и модель БД под названием «Users», которая содержит лат и атрибут lon и метод для расчета расстояния haversine.

    class Users(UserMixin, db.Model):
        __tablename__ = "users"
        # STATIC Standard required info
        id = db.Column("id", db.Integer, primary_key = True)
        public_id = db.Column("public_id", db.String(50), unique = True)
        email = db.Column("email", db.String(50), unique = True)
        username = db.Column("username", db.String(20), unique = True)
        password = db.Column("password", db.String(20))

        # DYNAMIC Standard required info
        lat = db.Column("lat", db.Float)
        lon = db.Column("lon", db.Float)

        def distanceMath(self, lat1, lon1, math=math):
            coords1 = (lat1, lon1)
            coords2 = (self.lat, self.lon)
            return mpu.haversine_distance(coords1, coords2)

        def __init__(self, public_id, email, username, password):
            self.public_id = public_id
            self.email = email
            self.username = username
            self.password = password
            self.lat = None
            self.lon = None

На одном из моих маршрутов я пытаюсь выполнить расчет расстояния хаверсин в запросе, например так:

    users = Users.query.filter(current_user.distanceMath(lat1, lon1) <= 25).all()

Но этот запрос не работает по назначению, так как distanceMath не получает значения lat и lon каждой строки во время запроса, а вместо этого получает только одну строку lat и lon. У меня есть вторая функция distanceMath, которая должна использоваться вне запросов, которая возвращает правильные расстояния, потому что она принимает значения lat и lon из переменной user, инициализированной после ошибочного запроса.

    for user in users:
        data = {}
        data["username"] = user.username
        data["lat"] = user.lat
        data["lon"] = user.lon
        data["distance"] = distanceMath(current_user.lat, current_user.lon, user.lat, user.lon)
        output.append(data)
    return str(output)

Этот цикл выводит:

    [{'username': 'beclops', 'lat': 37.785834, 'lon': 116.406417, 'distance': 3643.671611712818}, {'username': 'beclops2', 'lat': 40.0, 'lon': 74.0, 'distance': 0.0}]

Обратите внимание, что расстояние правильное, но этот пользователь не должен был возвращаться в фильтр запроса.

Мой общий вопрос: как мне это сделать, поскольку я пытался использовать raw sql в методе execute (), и это возвращает ошибку, в которой говорится, например, «Нет такой функции, как SQRT», при использовании sqlalchemy Формат ORM не позволяет мне получать доступ к актуальным значениям lat и lon во время запроса.

Большое спасибо, и извините за длину вопроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...