metricq / aiocouch

🛋 An asynchronous client library for CouchDB 2.x and 3.x
https://aiocouch.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
29 stars 10 forks source link

Issue with Sort of /db/_find #40

Closed dradux closed 2 years ago

dradux commented 2 years ago

When I specify a sort with any values defined I get the following error:

trax-api-1  | ERROR:    Exception in ASGI application
trax-api-1  | Traceback (most recent call last):
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 157, in wrapper
trax-api-1  |     return await func(endpoint, *args, **kwargs)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 161, in wrapper
trax-api-1  |     raise exception
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 157, in wrapper
trax-api-1  |     return await func(endpoint, *args, **kwargs)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 161, in wrapper
trax-api-1  |     raise exception
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 157, in wrapper
trax-api-1  |     return await func(endpoint, *args, **kwargs)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 161, in wrapper
trax-api-1  |     raise exception
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 157, in wrapper
trax-api-1  |     return await func(endpoint, *args, **kwargs)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/remote.py", line 246, in _find
trax-api-1  |     _, json = await self._remote._post(f"{self.endpoint}/_find", data)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/remote.py", line 114, in _post
trax-api-1  |     return await self._request("POST", path, json=data, params=params)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/remote.py", line 142, in _request
trax-api-1  |     resp.raise_for_status()
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiohttp/client_reqrep.py", line 1000, in raise_for_status
trax-api-1  |     raise ClientResponseError(
trax-api-1  | aiohttp.client_exceptions.ClientResponseError: 400, message='Bad Request', url=URL('http://db:5984/activities/_find')
trax-api-1  | 
trax-api-1  | The above exception was the direct cause of the following exception:
trax-api-1  | 
trax-api-1  | Traceback (most recent call last):
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 373, in run_asgi
trax-api-1  |     result = await app(self.scope, self.receive, self.send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
trax-api-1  |     return await self.app(scope, receive, send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/fastapi/applications.py", line 208, in __call__
trax-api-1  |     await super().__call__(scope, receive, send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
trax-api-1  |     await self.middleware_stack(scope, receive, send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
trax-api-1  |     raise exc
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
trax-api-1  |     await self.app(scope, receive, _send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 84, in __call__
trax-api-1  |     await self.app(scope, receive, send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
trax-api-1  |     raise exc
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
trax-api-1  |     await self.app(scope, receive, sender)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 656, in __call__
trax-api-1  |     await route.handle(scope, receive, send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 259, in handle
trax-api-1  |     await self.app(scope, receive, send)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 61, in app
trax-api-1  |     response = await func(request)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 226, in app
trax-api-1  |     raw_response = await run_endpoint_function(
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 159, in run_endpoint_function
trax-api-1  |     return await dependant.call(**values)
trax-api-1  |   File "/app/./activities/routes.py", line 91, in get_all
trax-api-1  |     async for doc in db.find(selector=selector, limit=limit, skip=skip, sort=[{"created": "desc"}]):
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/database.py", line 221, in find
trax-api-1  |     async for doc in FindRequest(self, selector, limit, **params):
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/request.py", line 80, in __aiter__
trax-api-1  |     await self.database._find(
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 160, in wrapper
trax-api-1  |     raise_for_endpoint(endpoint, message, exception, exception_type)
trax-api-1  |   File "/usr/local/lib/python3.9/site-packages/aiocouch/exception.py", line 144, in raise_for_endpoint
trax-api-1  |     raise exception_type(message.format(**message_input)) from exception
trax-api-1  | aiocouch.exception.BadRequestError: Invalid request

I'm calling this with as:

async for doc in db.find(selector=selector, limit=limit, skip=skip, sort=[{"created": "desc"}]):
  ...

If I set sort=[] I do not get an error but I also get no sorting.

bmario commented 2 years ago

I've toyed around for a while, but this isn't a problem in aiocouch. It's a bit hidden, but the CouchDB documentation states that you need to have an index on the fields you're trying to sort (and in that particular order). 95eca75368c63e7e8a95a84d29200d2a00b2fe7e adds support to create indexes and a test case for find with sorting. It seems to work that way.

dradux commented 2 years ago

Thanks for the quick response and work. I've verified that creating an index on the sort column does fix the issue. I can submit a PR to add a note to the docs for this if you like?