Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Trino Python client

Client for Trino, 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.

Build StatusTrino SlackTrino: The Definitive Guide book download

Development

See DEVELOPMENT for information about code style, development process, and guidelines.

See CONTRIBUTING for contribution requirements.

Usage

The Python Database API (DBAPI)

Installation

$ pip install trino

Quick Start

Use the DBAPI interface to query Trino:

if host is a valid url, the port and http schema will be automatically determined. For example https://my-trino-server:9999 will assign the http_schema property to https and port to 9999.

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 the system.runtime.nodes system tables that shows the nodes in the Trino cluster.

The DBAPI implementation in trino.dbapi provides methods to retrieve fewer rows for example Cursor.fetchone() or Cursor.fetchmany(). By default Cursor.fetchmany() fetches one row. Please set trino.dbapi.Cursor.arraysize accordingly.

SQLAlchemy

Prerequisite

  • Trino server >= 351

Compatibility

trino.sqlalchemy is 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]

Usage

To connect to Trino using SQLAlchemy, use a connection string (URL) following this pattern:

trino://<username>:<password>@<host>:<port>/<catalog>/<schema>

NOTE: password and schema are optional

Examples:

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 use connect_args method. 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 mechanisms

Basic authentication

The BasicAuthentication class can be used to connect to a Trino cluster configured with the Password file, LDAP or Salesforce authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
    user="<username>",
    auth=BasicAuthentication("<username>", "<password>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The JWTAuthentication class can be used to connect to a Trino cluster configured with the JWT authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportJWTAuthenticationconn=connect(
    user="<username>",
    auth=JWTAuthentication("<jwt_token>"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The OAuth2Authentication class can be used to connect to a Trino cluster configured with the OAuth2 authentication type.

A callback to handle the redirect url can be provided via param redirect_auth_url_handler of the trino.auth.OAuth2Authentication class. 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 the trino.auth.CompositeRedirectHandler class.

The OAuth2 token will be cached either per trino.auth.OAuth2Authentication instance 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 using pip install 'trino[external-authentication-token-cache]'.

Warning

If username is not specified then the OAuth2 token cache is shared and stored per host.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportOAuth2Authenticationconn=connect(
    user="<username>",
    auth=OAuth2Authentication(),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportOAuth2Authenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": OAuth2Authentication(),
    "http_scheme": "https",
    }
    )

Certificate authentication

CertificateAuthentication class can be used to connect to Trino cluster configured with certificate based authentication. CertificateAuthentication requires paths to a valid client certificate and private key.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportCertificateAuthenticationconn=connect(
    user="<username>",
    auth=CertificateAuthentication("/path/to/cert.pem", "/path/to/key.pem"),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_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 authentication

The KerberosAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportKerberosAuthenticationconn=connect(
    user="<username>",
    auth=KerberosAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportKerberosAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": KerberosAuthentication(...),
    "http_scheme": "https",
    }
    )

GSSAPI authentication

The GSSAPIAuthentication class can be used to connect to a Trino cluster configured with the Kerberos authentication type:

It follows the interface for KerberosAuthentication, but is using requests-gssapi, instead of requests-kerberos under the hood.

  • DBAPI

    fromtrino.dbapiimportconnectfromtrino.authimportGSSAPIAuthenticationconn=connect(
    user="<username>",
    auth=GSSAPIAuthentication(...),
    http_scheme="https",
    ...
    )
  • SQLAlchemy

    fromsqlalchemyimportcreate_enginefromtrino.authimportGSSAPIAuthenticationengine=create_engine(
    "trino://<username>@<host>:<port>/<catalog>",
    connect_args={
    "auth": GSSAPIAuthentication(...),
    "http_scheme": "https",
    }
    )

User impersonation

In 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 set username to be different from principal_id. Note that principal_id is extracted from auth, for example username in BasicAuthentication, sub in JWT token or service-name in KerberosAuthentication. You need to make sure that principal_id has permission to impersonate username.

Extra credentials

Extra credentials can 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()

Roles

Authorization roles to use for catalogs, specified as a dict with key-value pairs for the catalog and role. For example, {"catalog1": "roleA", "catalog2": "roleB"} sets roleA for catalog1 and roleB for catalog2. See Trino docs.

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles={"catalog1": "roleA", "catalog2": "roleB"},
)

You could also pass system role without explicitly specifing "system" catalog:

importtrinoconn=trino.dbapi.connect(
host='localhost',
port=443,
user='the-user',
roles="role1"# equivalent to {"system": "role1"}
)

Timezone

The 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 pass timezone='UTC' when creating the connection.

SSL

SSL verification

In order to disable SSL verification, set the verify parameter to False.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify=False
)

Self-signed certificates

To use self-signed certificates, specify a path to the certificate in verify parameter. More details can be found in the Python requests library documentation.

fromtrino.dbapiimportconnectfromtrino.authimportBasicAuthenticationconn=connect(
user="<username>",
auth=BasicAuthentication("<username>", "<password>"),
http_scheme="https",
verify="/path/to/cert.crt"
)

Transactions

The client runs by default in autocommit mode. To enable transactions, set isolation_level to a value different than IsolationLevel.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 the with context and the queries succeed, otherwise trino.dbapi.Connection.rollback() will be called.

Legacy Primitive types

By default, the client will convert the results of the query to the corresponding Python types. For example, if the query returns a DECIMAL column, the result will be a Decimal object. If you want to disable this behaviour, set flag legacy_primitive_types to True.

Limitations of the Python types are described in the Python types documentation. These limitations will generate an exception trino.exceptions.TrinoDataError if 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 mappings

Trino typePython type
BOOLEANbool
TINYINTint
SMALLINTint
INTEGERint
BIGINTint
REALfloat
DOUBLEfloat
DECIMALdecimal.Decimal
VARCHARstr
CHARstr
VARBINARYbytes
DATEdatetime.date
TIMEdatetime.time
TIMESTAMPdatetime.datetime
ARRAYlist
MAPdict
ROWtuple

Trino types other than those listed above are not mapped to Python types. To use those use legacy 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-client channel on Trino Slack.

About

Python client for Trino

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages