Я не уверен, что это невозможно, или я что-то упустил, но у меня есть сервер 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 во время запроса.
Большое спасибо, и извините за длину вопроса.