考虑来自 https://postgrest.org/en/stable/references/api/tables_views.html#operator-modifiers:
的第一个“运算符修饰符”示例curl "http://localhost:3000/people?last_name=like(any).{O*,P*}"
如果我尝试使用
httpx
(或 requests
、urllib3
或我尝试过的任何其他 Python 模块)复制它,则以 PostgREST
结尾的 URL 是经过 urlencoded 的:
>>> import https
>>> r = httpx.get("http://localhost:3000/people?last_name=like(any).{O*,P*}")
>>> print(r.url)
URL('http://localhost:3000/people?last_name=like(any).%7BO*,P*%7D')
PostgREST
响应错误:
{'code': '22P02',
'details': 'Expected ":", but found "}".',
'hint': None,
'message': 'invalid input syntax for type json'}
客户端似乎无法禁用自动urlencoding。
如何使用
PostgREST
查询httpx
?
这里的问题与 URL 编码无关。 URL 编码是标准所要求的,如果 postgrest 确实存在问题,那么它就会有问题。
问题是你的
curl
命令行没有按照你想象的那样做。
curl
对待 {a,b,c}
表达式有点像 shell:它将展开而不是多个不同的 URL。所以当你写:
curl "http://localhost:3000/people?last_name=like(any).{O*,P*}"
您正在有效地运行多个
curl
命令:
curl "http://localhost:3000/people?last_name=like(any).O*"
curl "http://localhost:3000/people?last_name=like(any).P*"
我想您会发现您可以使用
httpx
(等)毫无问题地请求上述任一 URL。
这只是我的猜测,我会把它写在评论中而不是答案中,但遗憾的是我没有足够的声誉。请您测试一下并报告我的猜测是否正确?
Python HTTP 客户端(例如 httpx)会自动对 URL 参数进行编码,以确保它们遵循标准 URL 格式。这意味着
{
、}
和 *
等特殊字符是百分比编码的。例如,{
变为 %7B
,}
变为 %7D
,*
变为 %2A
。这是一种典型的行为,旨在防止包含可能被服务器或中间网络设备错误解释的字符的 URL 出现问题。
当您使用curl时,URL通常按原样使用,没有自动编码。这意味着服务器准确接收您在命令中键入的内容。在您的情况下,curl 发送带有未编码的大括号和星号的查询参数。
我不认为有办法在httpx中禁用http编码,但是你可以尝试用urllib测试它(默认情况下它没有http编码)
import urllib.request
# Manually construct the entire URL
url = "http://localhost:3000/people?last_name=like(any).{O*,P*}"
# Create a request object
req = urllib.request.Request(url)
# Open the URL and fetch the response
with urllib.request.urlopen(req) as response:
# Read and print the content (if you wish to see it)
content = response.read()
# Print the final URL used
print(req.full_url)