如何将原始 SQL 查询转换为 gino ORM 查询?
How to convert raw SQL query to gino ORM query?
我在 postgreSQL
数据库中有这个 table 安装并启用了 postGIS
扩展。
Table "public.crime_data"
Column | Type | Collation | Nullable | Default
-------------|-----------------------------|-----------|----------|----------------------------------------
id | integer | | not null | nextval('crime_data_id_seq'::regclass)
state | character varying | | |
district | character varying | | |
location | character varying | | |
sub_type_id | integer | | |
date_time | timestamp without time zone | | |
latitude | double precision | | |
longitude | double precision | | |
geom_point | geography(Point,4326) | | |
Indexes:
"crime_data_pkey" PRIMARY KEY, btree (id)
"idx_crime_data_geom_point" gist (geom_point)
Foreign-key constraints:
"crime_data_sub_type_id_fkey" FOREIGN KEY (sub_type_id) REFERENCES sub_type(id)
我正在使用 Sanic
网络框架,并与它一起使用 Gino ORM
因为它是异步的。
我能够在命令行中编写 运行 原始 SQL 查询,也可以使用 Gino
。我只想知道是否可以将某个查询转换为 ORM 语法。
这是有效 的原始查询。此代码片段位于异步视图函数内,这是 return 预期结果。
data_points = await db.status(db.text('''
SELECT
location,
sub_type_id,
latitude,
longitude,
date_time
FROM
crime_data
WHERE
ST_Distance(
geom_point,
ST_SetSRID(ST_MakePoint(:lng, :lat), 4326)
) <= 5 * 1609.34;
'''), {
'lat': lat,
'lng': lng,
})
这是我尝试将其转换为 ORM 查询的尝试,无法正常工作。
data_points = await CrimeData.query.where(
geo_func.ST_Distance(
'geom_point',
geo_func.ST_SetSRID(
geo_func.ST_MakePoint(lng, lat),
4326
)
) <= (5 * 1609.34)
).gino.all()
在尝试 运行 此查询和 return 作为 text
的响应时,出现此错误。
⚠️ 500 — Internal Server Error
parse error - invalid geometry HINT: "ge" <-- parse error at position 2 within geometry
Traceback of __main__ (most recent call last):
InternalServerError: parse error - invalid geometry HINT: "ge" <-- parse error at position 2 within geometry
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/sanic/app.py, line 973, in handle_request
response = await response
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/backend/services/crime_plot.py, line 30, in test
data_points = await CrimeData.query.where(
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/api.py, line 127, in all
return await self._query.bind.all(self._query, *multiparams, **params)
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/engine.py, line 740, in all
return await conn.all(clause, *multiparams, **params)
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/engine.py, line 316, in all
return await result.execute()
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/dialects/base.py, line 214, in execute
rows = await cursor.async_execute(
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/dialects/asyncpg.py, line 184, in async_execute
result, stmt = await getattr(conn, "_do_execute")(query, executor, timeout)
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/asyncpg/connection.py, line 1433, in _do_execute
result = await executor(stmt, None)
File asyncpg/protocol/protocol.pyx, line 196, in bind_execute
InternalServerError: parse error - invalid geometry HINT: "ge" <-- parse error at position 2 within geometry while handling path /crime-plot/test1
我知道 ORM 查询是一个 SELECT *
,只要我实际得到结果就可以了。我不明白我做错了什么。我正在完成工作,但我只想确保 ORM 也可行。
这是相关的视图函数代码。
@app.route('/test')
async def test(request):
"""
/test?lng=88.21927070000001&lat=23.9130464
"""
lat = request.args.get('lat')
lng = request.args.get('lng')
if lat and lng:
lat = float(lat)
lng = float(lng)
data_points = ... # either of the above mentioned queries
return text(data_points)
else:
return text('ERROR: lat or lng value missing')
由于您使用的是 ORM,因此您需要使用模型 class 的属性而不是列名称的字符串。将 ORM 查询更改为此,它应该可以工作。
data_points = await CrimeData.query.where(
geo_func.ST_Distance(
CrimeData.geom_point,
geo_func.ST_SetSRID(
geo_func.ST_MakePoint(lng, lat),
4326
)
) <= (5 * 1609.34)
).gino.all()
我在 postgreSQL
数据库中有这个 table 安装并启用了 postGIS
扩展。
Table "public.crime_data"
Column | Type | Collation | Nullable | Default
-------------|-----------------------------|-----------|----------|----------------------------------------
id | integer | | not null | nextval('crime_data_id_seq'::regclass)
state | character varying | | |
district | character varying | | |
location | character varying | | |
sub_type_id | integer | | |
date_time | timestamp without time zone | | |
latitude | double precision | | |
longitude | double precision | | |
geom_point | geography(Point,4326) | | |
Indexes:
"crime_data_pkey" PRIMARY KEY, btree (id)
"idx_crime_data_geom_point" gist (geom_point)
Foreign-key constraints:
"crime_data_sub_type_id_fkey" FOREIGN KEY (sub_type_id) REFERENCES sub_type(id)
我正在使用 Sanic
网络框架,并与它一起使用 Gino ORM
因为它是异步的。
我能够在命令行中编写 运行 原始 SQL 查询,也可以使用 Gino
。我只想知道是否可以将某个查询转换为 ORM 语法。
这是有效 的原始查询。此代码片段位于异步视图函数内,这是 return 预期结果。
data_points = await db.status(db.text('''
SELECT
location,
sub_type_id,
latitude,
longitude,
date_time
FROM
crime_data
WHERE
ST_Distance(
geom_point,
ST_SetSRID(ST_MakePoint(:lng, :lat), 4326)
) <= 5 * 1609.34;
'''), {
'lat': lat,
'lng': lng,
})
这是我尝试将其转换为 ORM 查询的尝试,无法正常工作。
data_points = await CrimeData.query.where(
geo_func.ST_Distance(
'geom_point',
geo_func.ST_SetSRID(
geo_func.ST_MakePoint(lng, lat),
4326
)
) <= (5 * 1609.34)
).gino.all()
在尝试 运行 此查询和 return 作为 text
的响应时,出现此错误。
⚠️ 500 — Internal Server Error
parse error - invalid geometry HINT: "ge" <-- parse error at position 2 within geometry
Traceback of __main__ (most recent call last):
InternalServerError: parse error - invalid geometry HINT: "ge" <-- parse error at position 2 within geometry
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/sanic/app.py, line 973, in handle_request
response = await response
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/backend/services/crime_plot.py, line 30, in test
data_points = await CrimeData.query.where(
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/api.py, line 127, in all
return await self._query.bind.all(self._query, *multiparams, **params)
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/engine.py, line 740, in all
return await conn.all(clause, *multiparams, **params)
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/engine.py, line 316, in all
return await result.execute()
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/dialects/base.py, line 214, in execute
rows = await cursor.async_execute(
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/gino/dialects/asyncpg.py, line 184, in async_execute
result, stmt = await getattr(conn, "_do_execute")(query, executor, timeout)
File /home/disciple/Documents/Code/MyProject-All/MyProject-Sanic/venv/lib/python3.8/site-packages/asyncpg/connection.py, line 1433, in _do_execute
result = await executor(stmt, None)
File asyncpg/protocol/protocol.pyx, line 196, in bind_execute
InternalServerError: parse error - invalid geometry HINT: "ge" <-- parse error at position 2 within geometry while handling path /crime-plot/test1
我知道 ORM 查询是一个 SELECT *
,只要我实际得到结果就可以了。我不明白我做错了什么。我正在完成工作,但我只想确保 ORM 也可行。
这是相关的视图函数代码。
@app.route('/test')
async def test(request):
"""
/test?lng=88.21927070000001&lat=23.9130464
"""
lat = request.args.get('lat')
lng = request.args.get('lng')
if lat and lng:
lat = float(lat)
lng = float(lng)
data_points = ... # either of the above mentioned queries
return text(data_points)
else:
return text('ERROR: lat or lng value missing')
由于您使用的是 ORM,因此您需要使用模型 class 的属性而不是列名称的字符串。将 ORM 查询更改为此,它应该可以工作。
data_points = await CrimeData.query.where(
geo_func.ST_Distance(
CrimeData.geom_point,
geo_func.ST_SetSRID(
geo_func.ST_MakePoint(lng, lat),
4326
)
) <= (5 * 1609.34)
).gino.all()