Beispiel #1
0
    async def _execute(self, query: str, *args) -> AsyncGenerator[Record, None]:
        query_type = self.query_type(query)

        if query_type == QueryTypes.FETCH:
            query += " FORMAT TSVWithNamesAndTypes"
        if args:
            if query_type != QueryTypes.INSERT:
                raise ChClientError(
                    "It is possible to pass arguments only for INSERT queries"
                )
            params = {**self.params, "query": query}
            if 'FORMAT JSONEachRow' in query:
                data = json2ch(*args)
            else:
                data = rows2ch(*args)
        else:
            params = self.params
            data = query.encode()

        async with self._session.post(
            self.url, params=params, data=data
        ) as resp:  # type: client.ClientResponse
            if resp.status != 200:
                raise ChClientError((await resp.read()).decode(errors='replace'))
            if query_type == QueryTypes.FETCH:
                rf = RecordsFabric(
                    names=await resp.content.readline(),
                    tps=await resp.content.readline(),
                )
                async for line in resp.content:
                    yield rf.new(line)
Beispiel #2
0
    async def _execute(
        self,
        query: str,
        *args,
        json: bool = False,
        query_params: Optional[Dict[str, Any]] = None,
    ) -> AsyncGenerator[Record, None]:
        query_params = self._prepare_query_params(query_params)
        query = query.format(**query_params)
        need_fetch, is_json, statement_type = self._parse_squery(query)

        if not is_json and json:
            query += " FORMAT JSONEachRow"
            is_json = True

        if not is_json and need_fetch:
            query += " FORMAT TSVWithNamesAndTypes"

        if args:
            if statement_type != 'INSERT':
                raise ChClientError(
                    "It is possible to pass arguments only for INSERT queries")
            params = {**self.params, "query": query}

            if is_json:
                data = json2ch(*args, dumps=self._json.dumps)
            else:
                data = rows2ch(*args)
        else:
            params = self.params
            data = query.encode()

        async with self._session.post(
                self.url, params=params,
                data=data) as resp:  # type: client.ClientResponse
            if resp.status != 200:
                raise ChClientError((await
                                     resp.read()).decode(errors='replace'))
            if need_fetch:
                if is_json:
                    rf = FromJsonFabric(loads=self._json.loads)
                    async for line in resp.content:
                        yield rf.new(line)
                else:
                    rf = RecordsFabric(
                        names=await resp.content.readline(),
                        tps=await resp.content.readline(),
                    )
                    async for line in resp.content:
                        yield rf.new(line)
Beispiel #3
0
def what_py_type(name: str, container: bool = False) -> BaseType:
    """ Returns needed type class from clickhouse type name """
    name = name.strip()
    try:
        return CH_TYPES_MAPPING[name.split("(")[0]](name, container=container)
    except KeyError:
        raise ChClientError(f"Unrecognized type name: '{name}'")
Beispiel #4
0
def py2ch(value):
    try:
        return PY_TYPES_MAPPING[type(value)](value)
    except KeyError:
        raise ChClientError(
            f"Unrecognized type: '{type(value)}'. "
            f"The value type should be exactly one of "
            f"int, float, str, dt.date, dt.datetime, tuple, list, uuid.UUID (or None). "
            f"No subclasses yet.")
Beispiel #5
0
    async def _execute(
        self,
        query: str,
        *args,
        json: bool = False,
        query_params: Optional[Dict[str, Any]] = None,
        query_id: str = None,
    ) -> AsyncGenerator[Record, None]:
        query_params = self._prepare_query_params(query_params)
        query = query.format(**query_params)
        need_fetch, is_json, statement_type = self._parse_squery(query)

        if not is_json and json:
            query += " FORMAT JSONEachRow"
            is_json = True

        if not is_json and need_fetch:
            query += " FORMAT TSVWithNamesAndTypes"

        if args:
            if statement_type != 'INSERT':
                raise ChClientError(
                    "It is possible to pass arguments only for INSERT queries"
                )
            params = {**self.params, "query": query}

            if is_json:
                data = json2ch(*args, dumps=self._json.dumps)
            else:
                data = rows2ch(*args)
        else:
            params = {**self.params}
            data = query.encode()

        if query_id is not None:
            params["query_id"] = query_id

        if need_fetch:
            response = self._http_client.post_return_lines(
                url=self.url, params=params, data=data
            )
            if is_json:
                rf = FromJsonFabric(loads=self._json.loads)
                async for line in response:
                    yield rf.new(line)
            else:
                rf = RecordsFabric(
                    names=await response.__anext__(),
                    tps=await response.__anext__(),
                )
                async for line in response:
                    yield rf.new(line)
        else:
            await self._http_client.post_no_return(
                url=self.url, params=params, data=data
            )
Beispiel #6
0
def what_py_type(name: str, container: bool = False) -> BaseType:
    """Returns needed type class from clickhouse type name"""
    name = name.strip()
    try:
        if name.startswith('SimpleAggregateFunction') or name.startswith(
            'AggregateFunction'
        ):
            ch_type = re.findall(r',(.*)\)', name)[0].strip()
        else:
            ch_type = name.split("(")[0]
        return CH_TYPES_MAPPING[ch_type](name, container=container)
    except KeyError:
        raise ChClientError(f"Unrecognized type name: '{name}'")
Beispiel #7
0
    def choose_http_client(session):
        try:
            import aiohttp

            if session is None or isinstance(session, aiohttp.ClientSession):
                from aiochclient.http_clients.aiohttp import AiohttpHttpClient

                return AiohttpHttpClient
        except ImportError:
            pass
        try:
            import httpx

            if session is None or isinstance(session, httpx.AsyncClient):
                from aiochclient.http_clients.httpx import HttpxHttpClient

                return HttpxHttpClient
        except ImportError:
            pass
        raise ChClientError('Async http client heeded. Please install aiohttp or httpx')
Beispiel #8
0
async def _check_response(resp):
    if resp.status != 200:
        raise ChClientError(await _read_error_body(resp))