Python 如何在SQLAlchemy中传递过滤条件中的模型参数

Python 如何在SQLAlchemy中传递过滤条件中的模型参数,python,sqlalchemy,Python,Sqlalchemy,我正在使用SQLAlchemy来处理我目前正在开发的Flask webapp的数据库。作为网站的一项功能,我希望用户能够以指定位置的位置和半径作为参数搜索其他用户。所以很自然地,我对SQLAlchemy了解不多,我试着用这个表达: profiles = User.query.filter(sqrt(abs(User.latitude - location.latitude)**2 + abs(User.longitude - location.longitude)**2) <= radiu

我正在使用SQLAlchemy来处理我目前正在开发的Flask webapp的数据库。作为网站的一项功能,我希望用户能够以指定位置的位置和半径作为参数搜索其他用户。所以很自然地,我对SQLAlchemy了解不多,我试着用这个表达:

profiles = User.query.filter(sqrt(abs(User.latitude - location.latitude)**2 + abs(User.longitude - location.longitude)**2) <= radius)
profiles = User.query.filter(User.is_nearby(latitude=location.latitude, longitude=location.longitude, radius=radius))
(我还删除了表达式中的
abs()
函数,因为平方运算已经返回了唯一的正值..)

这是我的路线,而不是旧的表达:

profiles = User.query.filter(sqrt(abs(User.latitude - location.latitude)**2 + abs(User.longitude - location.longitude)**2) <= radius)
profiles = User.query.filter(User.is_nearby(latitude=location.latitude, longitude=location.longitude, radius=radius))
(仅供参考,然后我保存了代码,更新了数据库并重新启动了flask服务器)

我再次尝试了查询搜索,然后。。。 我得到了这个错误:

Traceback (most recent call last):
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2309, in __call__
   return self.wsgi_app(environ, start_response)
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2295, in wsgi_app
   response = self.handle_exception(e)
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1741, in handle_exception
   reraise(exc_type, exc_value, tb)
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
   raise value
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2292, in wsgi_app
   response = self.full_dispatch_request()
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
   rv = self.handle_user_exception(e)
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
   reraise(exc_type, exc_value, tb)
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
   raise value
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
   rv = self.dispatch_request()
 File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1799, in dispatch_request
   return self.view_functions[rule.endpoint](**req.view_args)
 File "C:\Users\Frederik\Desktop\start\app\routes.py", line 136, in explore
   profiles = User.query.filter_by(sqrt(abs(User.latitude - location.latitude)**2 + abs(User.longitude - location.longitude)**2) <= radius)
TypeError: bad operand type for abs(): 'BinaryExpression'
Traceback (most recent call last):
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Frederik\Desktop\start\app\routes.py", line 134, in explore
    profiles = User.query.filter(User.is_nearby(latitude=location.latitude, longitude=location.longitude, radius=radius))
  File "C:\Users\Frederik\Desktop\start\app\models.py", line 64, in is_nearby
    return sqrt((self.latitude - latitude)**2 + (self.longitude - longitude)**2) <= radius
TypeError: unsupported operand type(s) for ** or pow(): 'BinaryExpression' and 'int'
这是我的用户模型,它有两个与此问题相关的依赖项:

class User(UserMixin, db.Model):
    ...
    latitude = db.Column(db.Float, index=True)
    longitude = db.Column(db.Float, index=True)
    ...

为什么模型的这些属性不能应用于特定的操作数,即查询搜索中的条件内平方?在我的情况下,我该如何应对呢?

PS

非常感谢您对frost-nzcr4的评论。这意味着很多

编辑2 好的,现在根据frost-nzcr4的另一个建议,我将
is_nearest
方法更改为: (此处
func
引用了sqlalchemy导入func中的

而且它有效!它消除了以前的错误。。但接下来是另一个

Traceback (most recent call last):
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1244, in _execute_context
    cursor, statement, parameters, context
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\default.py", line 552, in do_execute
    cursor.execute(statement, parameters)
sqlite3.OperationalError: no such function: sqrt

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Frederik\Desktop\start\app\routes.py", line 135, in explore
    profiles = User.query.filter(User.is_nearby(latitude=location.latitude, longitude=location.longitude, radius=radius)).all()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\orm\query.py", line 3161, in all
    return list(self)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\orm\query.py", line 3317, in __iter__
    return self._execute_and_instances(context)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\orm\query.py", line 3342, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 988, in execute
    return meth(self, multiparams, params)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\sql\elements.py", line 287, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1107, in _execute_clauseelement
    distilled_params,
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1248, in _execute_context
    e, statement, parameters, cursor, context
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1466, in _handle_dbapi_exception
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\util\compat.py", line 383, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\util\compat.py", line 128, in reraise
    raise value.with_traceback(tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1244, in _execute_context
    cursor, statement, parameters, context
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\default.py", line 552, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such function: sqrt
[SQL: SELECT user.id AS user_id, user.name AS user_name, user.location AS user_location, user.latitude AS user_latitude, user.longitude AS user_longitude, user.username AS user_username, user.email AS user_email, user.password_hash AS user_password_hash
FROM user
WHERE sqrt(pow(user.latitude - ?, ?) + pow(user.longitude - ?, ?)) <= ?]
[parameters: (55.8125143, 2, 12.4687513, 2, '10')]
(Background on this error at: http://sqlalche.me/e/e3q8)
回溯(最近一次呼叫最后一次):
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\base.py”,第1244行,在执行上下文中
游标、语句、参数、上下文
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\default.py”,第552行,在do\u execute中
cursor.execute(语句、参数)
sqlite3.ERROR:没有这样的函数:sqrt
上述异常是以下异常的直接原因:
回溯(最近一次呼叫最后一次):
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第2309行,在调用中__
返回self.wsgi_应用程序(环境,启动响应)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第2295行,位于wsgi\u应用程序中
response=self.handle\u异常(e)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第1741行,位于句柄\u异常中
重放(exc_类型、exc_值、tb)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\\u compat.py”,第35行,在reraise中
增值
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第2292行,位于wsgi\u应用程序中
response=self.full\u dispatch\u request()
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第1815行,完全发送请求
rv=自身处理用户异常(e)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第1718行,在handle\u user\u异常中
重放(exc_类型、exc_值、tb)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\\u compat.py”,第35行,在reraise中
增值
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第1813行,完全发送请求
rv=自我分派请求()
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\flask\app.py”,第1799行,在调度请求中
返回self.view_函数[rule.endpoint](**req.view_参数)
文件“C:\Users\Frederik\Desktop\start\app\routes.py”,第135行,在explore中
profiles=User.query.filter(User.is_附近(纬度=位置.纬度,经度=位置.经度,半径=半径)).all()
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\orm\query.py”,第3161行,共
返回列表(自我)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\orm\query.py”,第3317行,在__
返回self.\u执行\u和\u实例(上下文)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\orm\query.py”,第3342行,在执行和实例中
结果=conn.execute(querycontext.statement,self.\u参数)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\base.py”,执行中第988行
返回方法(自身、多线程、参数)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\sql\elements.py”,第287行,在连接上执行
返回连接。_execute_clauseelement(self、multiparams、params)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\base.py”,第1107行,在执行条款元素中
你的参数,
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\base.py”,第1248行,在执行上下文中
e、 语句、参数、游标、上下文
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\base.py”,第1466行,在(句柄)dbapi(异常)中
util.raise\u from\u cause(sqlalchemy\u异常,exc\u信息)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\util\compat.py”,第383行,位于raise\u from\u cause中
重新释放(类型(异常),异常,tb=exc\U tb,原因=原因)
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\util\compat.py”,第128行,在reraise中
通过_回溯(tb)提升值
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\base.py”,第1244行,在执行上下文中
游标、语句、参数、上下文
文件“c:\users\frederik\appdata\local\programs\python\python37\lib\site packages\sqlalchemy\engine\default.py”,lin
profiles = User.query.filter(User.is_nearby(latitude=location.latitude, longitude=location.longitude, radius=radius)).all()
Traceback (most recent call last):
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1244, in _execute_context
    cursor, statement, parameters, context
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\default.py", line 552, in do_execute
    cursor.execute(statement, parameters)
sqlite3.OperationalError: no such function: sqrt

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\flask\app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Frederik\Desktop\start\app\routes.py", line 135, in explore
    profiles = User.query.filter(User.is_nearby(latitude=location.latitude, longitude=location.longitude, radius=radius)).all()
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\orm\query.py", line 3161, in all
    return list(self)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\orm\query.py", line 3317, in __iter__
    return self._execute_and_instances(context)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\orm\query.py", line 3342, in _execute_and_instances
    result = conn.execute(querycontext.statement, self._params)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 988, in execute
    return meth(self, multiparams, params)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\sql\elements.py", line 287, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1107, in _execute_clauseelement
    distilled_params,
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1248, in _execute_context
    e, statement, parameters, cursor, context
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1466, in _handle_dbapi_exception
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\util\compat.py", line 383, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\util\compat.py", line 128, in reraise
    raise value.with_traceback(tb)
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\base.py", line 1244, in _execute_context
    cursor, statement, parameters, context
  File "c:\users\frederik\appdata\local\programs\python\python37\lib\site-packages\sqlalchemy\engine\default.py", line 552, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such function: sqrt
[SQL: SELECT user.id AS user_id, user.name AS user_name, user.location AS user_location, user.latitude AS user_latitude, user.longitude AS user_longitude, user.username AS user_username, user.email AS user_email, user.password_hash AS user_password_hash
FROM user
WHERE sqrt(pow(user.latitude - ?, ?) + pow(user.longitude - ?, ?)) <= ?]
[parameters: (55.8125143, 2, 12.4687513, 2, '10')]
(Background on this error at: http://sqlalche.me/e/e3q8)