tddbapi 0.1.1
Pythonic shim over teradatasql, Teradata DB API driver
Requires Python: >=3.8

# tddbapi

[![PyPi](https://img.shields.io/pypi/v/tddbapi.svg)](https://pypi.python.org/pypi/tddbapi)
[![MIT License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
![Python3.8+](https://img.shields.io/pypi/pyversions/tddbapi.svg)

[tddbapi](https://bitbucket.org/padhia/tddbapi) is a DB API module that is a shim over [teradatasql](https://pypi.org/project/teradatasql), the Teradata provided DB API module. `teradatasql` closely follows Teradata JDBC driver in terms of functionality and behaviors, some of which, arguably aren't quite *pythonic*. `tddbapi` attempts to correct this by altering selected `teradatasql` behavior (APIs) as documented here. The remaining, unaltered, functionality is directly passed through to the `teradatasql` module.

## `teradatasql` behavior

1. Fixed-length character column values have incorrect length when accessed in Python. According to Teradata, this is [working as designed](https://github.com/Teradata/python-driver#CharacterExportWidth).

1. `teradatasql` uses `OperationalError` for all exceptions. According to Python's DB API specification, `OperationalError` is reserved for a certain class of errors. Additionally, the exception object
    * doesn't provide easy access to the *error code* or the *error message* values.
    * has text that includes unformatted stack trace of underlying *gosql* driver. While this may be useful in certain situations, for example, reporting errors back to Teradata, but may not be the best message to display to the users.

1. All SQL `INTERVAL` values are returned as Python type `str` instead of more appropriate native Python types, thus working with them is harder in Python. Apparently, this was done because not all SQL INTERVAL data types can be represented by Python's `datetime.timedelta` type.

1. `teradatasql` exposes all internally used names, and thus can pollute the *namespace* if you use `from teradatasql import *`.

## `tddbapi` behavior

1. Fixed-length character columns will have any extra spaces beyond their actual definition truncated.

1. Appropriate Exception raised for the *most common* errors. Exception objects:
    * have `sqlcode` and `sqltext` attributes that can be queried directly instead of having to parse the error message
    * provide `__str__` method that produces a human-readable error message and removes `gosql` stack-trace information
    * *note*: If you want to ensure that the exception handling logic works with `teradatasql` *and* `tddbapi`, use an Exception class that is higher in the hierarchy, for example, `DatabaseError` or `Error`

1. `INTERVAL` values are objects of either `datetime.timedelta` subclasses, or for the *month based* interval types, instances of `int` subclasses. The *month-based* intervals use the total number of months as canonical value, thus allowing comparison between two month-based intervals even if their exact types are different.

1. It's safe to code `from tddbapi import *` without introducing non DB-API names into the current namespace

**Note**
`tddbapi` always obtains resultset metadata information for all queries. If your application also needs access to resultset metadata, it can be accessed as `_meta` attribute of the cursor as already-parsed JSON data.

## Installation and Usage

Install `tddbapi` using the standard `pip` utility:

```
pip install --upgrade tddbapi
```

Using `tddbapi` in a Python application is as simple as replacing `teradatasql` with `tddbapi`. For example:

```python
import tddbapi as teradatasql

with teradatasql.connect(host="whomooz", user="guest", password="please") as con:
    with con.cursor() as cur:
        cur.execute("SELECT * FROM DBC.DBCINFOV")
        print(cur.fetchall())
```

## Disclaimers

`tddbapi` module:

1. **does not** come with any warranty and the user assumes all risks associated with its usage.
1. is **not** endorsed by Teradata.
1. overrides some internal `teradatasql` implementation details. It is possible that a future version of `teradatasql` can break `tddbapi`, at least for a short period.
1. will be kept compatible with `teradatasql` on a best-effort basis. If you must have the latest `teradatasql` all the time *and* cannot live with the risk of breakage, even for a short period, you shouldn't use this module.
1. is available via MIT license, which may be different from the licenses of any of its dependencies (currently only `teradatasql`).