Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/yassun7010/turu-py
Simple Database API for Typed Python
https://github.com/yassun7010/turu-py
async bigquery pep249 postgres postgresql postgresql-database python snowflake snowflakedb sqlite sqlite-database sqlite3 sqlite3-database typed-python
Last synced: 4 months ago
JSON representation
Simple Database API for Typed Python
- Host: GitHub
- URL: https://github.com/yassun7010/turu-py
- Owner: yassun7010
- Created: 2023-12-12T13:42:33.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-09-28T05:06:45.000Z (4 months ago)
- Last Synced: 2024-09-28T18:24:04.588Z (4 months ago)
- Topics: async, bigquery, pep249, postgres, postgresql, postgresql-database, python, snowflake, snowflakedb, sqlite, sqlite-database, sqlite3, sqlite3-database, typed-python
- Language: Python
- Homepage: https://yassun7010.github.io/turu-py/
- Size: 3.13 MB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Turu: Simple Database Client for Typed Python
[![docs](https://github.com/yassun7010/turu-py/actions/workflows/publish-mkdocs.yml/badge.svg)](https://yassun7010.github.io/turu-py/)
[![test](https://github.com/yassun7010/turu-py/actions/workflows/test-suite.yml/badge.svg)](https://github.com/yassun7010/turu-py/actions)
[![pypi package](https://badge.fury.io/py/turu.svg)](https://pypi.org/project/turu)
---
**Documentation**: https://yassun7010.github.io/turu-py/
**Source Code**: https://github.com/yassun7010/turu-py
---
## Installation
```bash
pip install "turu[snowflake]"
```## Why Turu?
SQL is a powerful language, but it has many dialects, and Cloud Native Databases are especially difficult to test automatically in a local environment.Turu was developed as a simple tool to assist local development.
It provides a simple interface according to [PEP 249 – Python Database API Specification v2.0](https://peps.python.org/pep-0249/) and allows for easy recording of query results and injection mock data.## Features
- :rocket: **Simple** - Turu is a simple database api wrapper of [PEP 249](https://peps.python.org/pep-0249/).
- :bulb: **Type Hint** - Full support for type hints.
- :zap: **Async/Await** - Async/Await supports.
- :test_tube: **Recoed and Mock** - Record and mock database queries for testing.## Supprted Database
| Database | Sync Support | Async Support | Installation |
| ---------- | ------------ | ------------- | ------------------------------- |
| SQLite3 | Yes | Yes | `pip install "turu[sqlite3]"` |
| MySQL | Yes | Yes | `pip install "turu[mysql]"` |
| PostgreSQL | Yes | Yes | `pip install "turu[postgres]"` |
| Snowflake | Yes | Yes | `pip install "turu[snowflake]"` |
| BigQuery | Yes | No | `pip install "turu[bigquery]"` |## Usage
### Basic Usage
```python
from pydantic import BaseModelclass Row(BaseModel):
id: int
name: strconnection = turu.sqlite3.connect("test.db")
with connection.cursor() as cursor:
assert cursor.execute_map(Row, "select 1, 'a'").fetchone() == Row(id=1, name="a")
```## Testing
```python
import turu.sqlite3from pydantic import BaseModel
class Row(BaseModel):
id: int
name: strexpected1 = [Row(id=1, name="a"), Row(id=2, name="b")]
expected2 = [Row(id=3, name="c"), Row(id=4, name="d")]
expected3 = [Row(id=5, name="e"), Row(id=6, name="f")]connection = turu.sqlite3.MockConnection()
(
connection.chain()
.inject_response(Row, expected1)
.inject_response(Row, expected2)
.inject_response(Row, expected3)
)for expected in [expected1, expected2, expected3]:
with connection.cursor() as cursor:
assert cursor.execute_map(Row, "select 1, 'a'").fetchall() == expected
```## Recording and Testing
Your Production Code
```python
import osimport turu.sqlite3
from turu.core.record import record_to_csvfrom your_package.data import RECORD_DIR
from your_package.schema import Rowdef do_something(connection: turu.sqlite3.Connection):
with record_to_csv(
RECORD_DIR / "test.csv",
connection.curosr(),
enable=os.environ.get("ENABLE_RECORDING"),
limit=100,
) as cursor:
... # Your logic
```Your Test Code
```python
import turu.sqlite3from your_package.data import RECORD_DIR
from your_package.schema import Rowdef test_do_something(connection: turu.sqlite3.MockConnection):
connection.inject_response_from_csv(Row, RECORD_DIR / "test.csv")assert do_something(connection) is None
```