ibis-project / ibis

the portable Python dataframe library
https://ibis-project.org
Apache License 2.0
5.06k stars 587 forks source link

bug: Trino connection issue #9956

Closed duruixue closed 1 week ago

duruixue commented 2 weeks ago

What happened?

Same issue reported here. I ran the following code snippet and got AttributeError: 'str' object has no attribute 'set_http_session':

import ibis

con = ibis.trino.connect(
    host="my_host",
    # auth=auth,
    user=username,
    auth=pwd,
    http_scheme="https",
    database="iceberg",
    schema="myschema",
)

t = con.table("table_name")
t

What version of ibis are you using?

9.3.0

What backend(s) are you using, if any?

Trino 0.329.0

Relevant log output

{
    "name": "AttributeError",
    "message": "'str' object has no attribute 'set_http_session'",
    "stack": "---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File /Users/paul/projects/tmp/tmp.py:11
      1 # %%
      2 con = ibis.trino.connect(
      3     host=\"my_host\",
      4     # auth=auth,
   (...)
      8     database=\"iceberg\",
      9 )
---> 11 t = con.table(\"table_name\")
     12 t

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/ibis/backends/sql/__init__.py:137, in SQLBackend.table(self, name, schema, database)
    134 catalog = table_loc.catalog or None
    135 database = table_loc.db or None
--> 137 table_schema = self.get_schema(name, catalog=catalog, database=database)
    138 return ops.DatabaseTable(
    139     name,
    140     schema=table_schema,
    141     source=self,
    142     namespace=ops.Namespace(catalog=catalog, database=database),
    143 ).to_expr()

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/ibis/backends/trino/__init__.py:151, in Backend.get_schema(self, table_name, catalog, database)
    117 def get_schema(
    118     self,
    119     table_name: str,
   (...)
    122     database: str | None = None,
    123 ) -> sch.Schema:
    124     \"\"\"Compute the schema of a `table`.
    125 
    126     Parameters
   (...)
    140 
    141     \"\"\"
    142     query = (
    143         sg.select(
    144             C.column_name,
    145             C.data_type,
    146             C.is_nullable.eq(sge.convert(\"YES\")).as_(\"nullable\"),
    147         )
    148         .from_(sg.table(\"columns\", db=\"information_schema\", catalog=catalog))
    149         .where(
    150             C.table_name.eq(sge.convert(table_name)),
--> 151             C.table_schema.eq(sge.convert(database or self.current_database)),
    152         )
    153         .order_by(C.ordinal_position)
    154     )
    156     with self._safe_raw_sql(query) as cur:
    157         meta = cur.fetchall()

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/ibis/backends/trino/__init__.py:186, in Backend.current_database(self)
    184 @property
    185 def current_database(self) -> str:
--> 186     with self._safe_raw_sql(sg.select(C.current_schema)) as cur:
    187         [(schema,)] = cur.fetchall()
    188     return schema

File ~/.pyenv/versions/3.11.8/lib/python3.11/contextlib.py:137, in _GeneratorContextManager.__enter__(self)
    135 del self.args, self.kwds, self.func
    136 try:
--> 137     return next(self.gen)
    138 except StopIteration:
    139     raise RuntimeError(\"generator didn't yield\") from None

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/ibis/backends/trino/__init__.py:110, in Backend._safe_raw_sql(self, query)
     93 @contextlib.contextmanager
     94 def _safe_raw_sql(
     95     self, query: str | sge.Expression
     96 ) -> Iterator[trino.dbapi.Cursor]:
     97     \"\"\"Execute a raw SQL query, yielding the cursor.
     98 
     99     Parameters
   (...)
    108 
    109     \"\"\"
--> 110     cur = self.raw_sql(query)
    111     try:
    112         yield cur

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/ibis/backends/trino/__init__.py:62, in Backend.raw_sql(self, query)
     59     query = query.sql(dialect=self.name, pretty=True)
     61 con = self.con
---> 62 cur = con.cursor()
     63 try:
     64     cur.execute(query)

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/trino/dbapi.py:264, in Connection.cursor(self, legacy_primitive_types)
    262     request = self.transaction.request
    263 else:
--> 264     request = self._create_request()
    265 return Cursor(
    266     self,
    267     request,
    268     # if legacy params are not explicitly set in Cursor, take them from Connection
    269     legacy_primitive_types if legacy_primitive_types is not None else self.legacy_primitive_types
    270 )

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/trino/dbapi.py:245, in Connection._create_request(self)
    244 def _create_request(self):
--> 245     return trino.client.TrinoRequest(
    246         self.host,
    247         self.port,
    248         self._client_session,
    249         self._http_session,
    250         self.http_scheme,
    251         self.auth,
    252         self.max_attempts,
    253         self.request_timeout,
    254     )

File ~/.pyenv/versions/3.11.8/envs/tmp/lib/python3.11/site-packages/trino/client.py:435, in TrinoRequest.__init__(self, host, port, client_session, http_session, http_scheme, auth, max_attempts, request_timeout, handle_retry, verify)
    433     if self._http_scheme == constants.HTTP:
    434         raise ValueError(\"cannot use authentication with HTTP\")
--> 435     self._auth.set_http_session(self._http_session)
    436     self._exceptions += self._auth.get_exceptions()
    438 self._request_timeout = request_timeout

AttributeError: 'str' object has no attribute 'set_http_session'"
}

Code of Conduct

cpcloud commented 2 weeks ago

We can probably make this a bit more convenient for the basic auth case, but in the meantime you can do use the Trino client's BasicAuthentication class, shown here: https://github.com/trinodb/trino-python-client#basic-authentication.