Metadata-Version: 2.4
Name: sql-artifex
Version: 0.62.0
Summary: Typed Python SQLite/PostgreSQL query builder.
Author: Matthew Burkard
Author-email: Matthew Burkard <matthew@burkard.cloud>
License-Expression: Apache-2.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: case-switcher>=1.3.13
Requires-Python: >=3.14
Project-URL: homepage, https://gitlab.com/mburkard/artifex
Project-URL: repository, https://gitlab.com/mburkard/artifex
Description-Content-Type: text/markdown

# Artifex

![](https://img.shields.io/badge/License-ApacheV2-blue.svg)
![](https://img.shields.io/badge/code%20style-black-000000.svg)
![](https://img.shields.io/badge/coverage-100%25-success)

Typed Python SQLite/PostgreSQL query builder.

This is in early development and may see massive refactor.

## Usage

Use `artifex` functions `delete, insert_into, select, update` to build a query. Then
call `prepare()` to get a tuple comprising a list of parameters used in the query and
the query itself. Anywhere a parameter was used in the query will be replaced with `?`,
this way the database can handle param binding.

### Black Formatted Example

```python
from sql_artifex import Column, Table, and_, join, select


class User(Table):
    id = Column()
    first = Column()
    last = Column()


class Note(Table):
    id = Column()
    user_id = Column()
    value = Column()


sql, params = (
    select(
        User.id,
        User.first,
        User.last,
        Note.id.as_("note_id"),
        Note.value,
    )
    .from_(
        User,
        join(Note).on(Note.user_id == User.id),
    )
    .where(
        User.id == 1,
        and_(Note.value == "test_note"),
    )
    .order_by(
        Note.value.desc(),
    )
).prepare()

assert params == [1, "test_note"]
expected = " ".join(
    [
        "SELECT",
        '"user".id,',
        '"user".first,',
        '"user".last,',
        '"note".id AS note_id,',
        '"note".value',
        'FROM "user"',
        'JOIN "note" ON "note".user_id = "user".id',
        'WHERE "user".id = ? AND "note".value = ?',
        'ORDER BY "note".value DESC',
    ]
)
assert sql == expected
```

### Create Table

```python
from sql_artifex import Column, Table
from sql_artifex.types import TEXT, TIMESTAMP, UUID


class User(Table):
    id = Column(UUID(), primary=True)
    email = Column(TEXT(), unique=True, index=True)
    first = Column(TEXT())
    last = Column(TEXT())
    verified_at = Column(TIMESTAMP(with_time_zone=True))


User.table_set_unique_together(User.fist, User.last)
print(User.table_get_create())
```

Prints:

```sql
CREATE TABLE IF NOT EXISTS "user" (
  "id" UUID PRIMARY KEY,
  "email" TEXT NOT NULL UNIQUE,
  "first" TEXT NOT NULL,
  "last" TEXT NOT NULL,
  "verified_at" TIMESTAMP WITH TIME ZONE NOT NULL
);
CREATE INDEX email_idx ON "user" (email);
```

## Support the Developer

<a href="https://www.buymeacoffee.com/mburkard" target="_blank">
  <img src="https://cdn.buymeacoffee.com/buttons/v2/default-blue.png" alt="Buy Me a Coffee"
       width="217"
       height="60"/>
</a>
