Package: trino
Trino Python clientClient forTrino, a distributed SQL engine for interactive and batch big data processing.
Provides a low-level client and a DBAPI 2.0 implementation and a SQLAlchemy adapter.
It supports Python>=3.8 and PyPy.DevelopmentSeeDEVELOPMENTfor information about code style,
development process, and guidelines.SeeCONTRIBUTINGfor contribution requirements.UsageThe Python Database API (DBAPI)Installation$ pip install trinoQuick StartUse the DBAPI interface to query Trino:ifhostis a valid url, the port and http schema will be automatically determined. For examplehttps://my-trino-server:9999will assign thehttp_schemaproperty tohttpsand port to9999.fromtrino.dbapiimportconnectconn=connect(host="<host>",port=<port>,user="<username>",catalog="<catalog>",schema="<schema>",)cur=conn.cursor()cur.execute("SELECT * FROM system.runtime.nodes")rows=cur.fetchall()This will query thesystem.runtime.nodessystem tables that shows the nodes
in the Trino cluster.The DBAPI implementation intrino.dbapiprovides methods to retrieve fewer
rows for exampleCursor.fetchone()orCursor.fetchmany(). By defaultCursor.fetchmany()fetches one row. Please settrino.dbapi.Cursor.arraysizeaccordingly.SQLAlchemyPrerequisiteTrino server >= 351Compatibilitytrino.sqlalchemyis compatible with the latest 1.3.x, 1.4.x and 2.0.x SQLAlchemy
versions at the time of release of a particular version of the client.Installation$ pip install trino[sqlalchemy]UsageTo connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:trino://<username>:<password>@<host>:<port>/<catalog>/<schema>NOTE:passwordandschemaare optionalExamples:fromsqlalchemyimportcreate_enginefromsqlalchemy.schemaimportTable,MetaDatafromsqlalchemy.sql.expressionimportselect,textengine=create_engine('trino://user@localhost:8080/system')connection=engine.connect()rows=connection.execute(text("SELECT * FROM runtime.nodes")).fetchall()# or using SQLAlchemy schemanodes=Table('nodes',MetaData(schema='runtime'),autoload=True,autoload_with=engine)rows=connection.execute(select(nodes)).fetchall()In order to pass additional connection attributes useconnect_argsmethod.
Attributes can also be passed in the connection string.fromsqlalchemyimportcreate_enginefromtrino.sqlalchemyimportURLengine=create_engine(URL(host="localhost",port=8080,catalog="system"),connect_args={"session_properties":{'query_max_run_time':'1d'},"client_tags":["tag1","tag2"],"roles":{"catalog1":"role1"},})# or in connection stringengine=create_engine('trino://user@localhost:8080/system?''session_properties={"query_max_run_time": "1d"}''&client_tags=["tag1", "tag2"]''&roles={"catalog1": "role1"}')# or using the URL factory methodengine=create_engine(URL(host="localhost",port=8080,client_tags=["tag1","tag2"]))Authentication mechanismsBasic authenticationTheBasicAuthenticationclass can be used to connect to a Trino cluster configured with
thePassword file, LDAP or Salesforce authentication type:DBAPIfromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(user="<username>",auth=BasicAuthentication("<username>","<password>"),http_scheme="https",...)SQLAlchemyfromsqlalchemyimportcreate_engineengine=create_engine("trino://<username>:<password>@<host>:<port>/<catalog>")# or as connect_argsfromtrino.authimportBasicAuthenticationengine=create_engine("trino://<username>@<host>:<port>/<catalog>",connect_args={"auth":BasicAuthentication("<username>","<password>"),"http_scheme":"https",})JWT authenticationTheJWTAuthenticationclass can be used to connect to a Trino cluster configured with
theJWTauthentication type:DBAPIfromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(user="<username>",auth=JWTAuthentication("<jwt_token>"),http_scheme="https",...)SQLAlchemyfromsqlalchemyimportcreate_engineengine=create_engine("trino://<username>@<host>:<port>/<catalog>/<schema>?access_token=<jwt_token>")# or as connect_argsfromtrino.authimportJWTAuthenticationengine=create_engine("trino://<username>@<host>:<port>/<catalog>",connect_args={"auth":JWTAuthentication("<jwt_token>"),"http_scheme":"https",})OAuth2 authenticationTheOAuth2Authenticationclass can be used to connect to a Trino cluster configured with
theOAuth2 authentication type.A callback to handle the redirect url can be provided via paramredirect_auth_url_handlerof thetrino.auth.OAuth2Authenticationclass. By default, it will try to launch a web browser (trino.auth.WebBrowserRedirectHandler) to go through the authentication flow and output the redirect url to stdout (trino.auth.ConsoleRedirectHandler). Multiple redirect handlers are combined using thetrino.auth.CompositeRedirectHandlerclass.The OAuth2 token will be cached either pertrino.auth.OAuth2Authenticationinstance and username or, when keyring is installed, it will be cached within a secure backend (MacOS keychain, Windows credential locker, etc) under a key including host of the Trino connection. Keyring can be installed usingpip install 'trino[external-authentication-token-cache]'.[!WARNING]
If username is not specified then the OAuth2 token cache is shared and stored per host.DBAPIfromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(user="<username>",auth=OAuth2Authentication(),http_scheme="https",...)SQLAlchemyfromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine("trino://<username>@<host>:<port>/<catalog>",connect_args={"auth":OAuth2Authentication(),"http_scheme":"https",})Certificate authenticationCertificateAuthenticationclass can be used to connect to Trino cluster configured withcertificate based authentication.CertificateAuthenticationrequires paths to a valid client certificate and private key.DBAPIfromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(user="<username>",auth=CertificateAuthentication("/path/to/cert.pem","/path/to/key.pem"),http_scheme="https",...)SQLAlchemyfromsqlalchemyimportcreate_enginefromtrino.authimportCertificateAuthenticationengine=create_engine("trino://<username>@<host>:<port>/<catalog>/<schema>?cert=<cert>&key=<key>")# or as connect_argsengine=create_engine("trino://<username>@<host>:<port>/<catalog>",connect_args={"auth":CertificateAuthentication("/path/to/cert.pem","/path/to/key.pem"),"http_scheme":"https",})Kerberos authenticationTheKerberosAuthenticationclass can be used to connect to a Trino cluster configured with
theKerberosauthentication type:DBAPIfromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(user="<username>",auth=KerberosAuthentication(...),http_scheme="https",...)SQLAlchemyfromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine("trino://<username>@<host>:<port>/<catalog>",connect_args={"auth":KerberosAuthentication(...),"http_scheme":"https",})User impersonationIn the case where user who submits the query is not the same as user who authenticates to Trino server (e.g in Superset),
you can setusernameto be different fromprincipal_id. Note thatprincipal_idis extracted fromauth,
for exampleusernamein BasicAuthentication,subin JWT token orservice-namein KerberosAuthentication.
You need to make sure thatprincipal_idhas permission to impersonateusername.Extra credentialsExtra credentialscan be sent as:importtrinoconn=trino.dbapi.connect(host='localhost',port=443,user='the-user',extra_credential=[('a.username','bar'),('a.password','foo')],)cur=conn.cursor()cur.execute('SELECT * FROM system.runtime.nodes')rows=cur.fetchall()RolesAuthorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example,{"catalog1": "roleA", "catalog2": "roleB"}setsroleAforcatalog1androleBforcatalog2. See Trino docs.importtrinoconn=trino.dbapi.connect(host='localhost',port=443,user='the-user',roles={"catalog1":"roleA","catalog2":"roleB"},)You could also passsystemrole without explicitly specifing "system" catalog:importtrinoconn=trino.dbapi.connect(host='localhost',port=443,user='the-user',roles="role1"# equivalent to {"system": "role1"})TimezoneThe time zone for the session can be explicitly set using the IANA time zone
name. When not set the time zone defaults to the client side local timezone.importtrinoconn=trino.dbapi.connect(host='localhost',port=443,user='username',timezone='Europe/Brussels',)NOTE: The behaviour till version 0.320.0 was the same as setting session timezone to UTC.To preserve that behaviour passtimezone='UTC'when creating the connection.SSLSSL verificationIn order to disable SSL verification, set theverifyparameter toFalse.fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(user="<username>",auth=BasicAuthentication("<username>","<password>"),http_scheme="https",verify=False)Self-signed certificatesTo use self-signed certificates, specify a path to the certificate inverifyparameter.
More details can be found inthe Python requests library documentation.fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(user="<username>",auth=BasicAuthentication("<username>","<password>"),http_scheme="https",verify="/path/to/cert.crt")TransactionsThe client runs by default inautocommitmode. To enable transactions, setisolation_levelto a value different thanIsolationLevel.AUTOCOMMIT:fromtrino.dbapiimportconnectfromtrino.transactionimportIsolationLevelwithconnect(isolation_level=IsolationLevel.REPEATABLE_READ,...)asconn:cur=conn.cursor()cur.execute('INSERT INTO sometable VALUES (1, 2, 3)')cur.fetchall()cur.execute('INSERT INTO sometable VALUES (4, 5, 6)')cur.fetchall()The transaction is created when the first SQL statement is executed.trino.dbapi.Connection.commit()will be automatically called when the code
exits thewithcontext and the queries succeed, otherwisetrino.dbapi.Connection.rollback()will be called.Legacy Primitive typesBy default, the client will convert the results of the query to the
corresponding Python types. For example, if the query returns aDECIMALcolumn, the result will be aDecimalobject.
If you want to disable this behaviour, set flaglegacy_primitive_typestoTrue.Limitations of the Python types are described in thePython types documentation. These limitations will generate an
exceptiontrino.exceptions.TrinoDataErrorif the query returns a value that cannot be converted to the corresponding Python
type.importtrinoconn=trino.dbapi.connect(legacy_primitive_types=True,...)cur=conn.cursor()# Negative DATE cannot be represented with Python types# legacy_primitive_types needs to be enabledcur.execute("SELECT DATE '-2001-08-22'")rows=cur.fetchall()assertrows[0][0]=="-2001-08-22"assertcur.description[0][1]=="date"Trino to Python type mappingsTrino typePython typeBOOLEANboolTINYINTintSMALLINTintINTEGERintBIGINTintREALfloatDOUBLEfloatDECIMALdecimal.DecimalVARCHARstrCHARstrVARBINARYbytesDATEdatetime.dateTIMEdatetime.timeTIMESTAMPdatetime.datetimeARRAYlistMAPdictROWtupleTrino types other than those listed above are not mapped to Python types. To use those uselegacy primitive types.Need help?Feel free to create an issue as it makes your request visible to other users and contributors.If an interactive discussion would be better or if you just want to hangout and chat about
the Trino Python client, you can join us on the#python-clientchannel onTrino Slack.