Skip to content

Commit 3aa857c

Browse files
committed
Add examples
1 parent cd83d45 commit 3aa857c

34 files changed

+1373
-0
lines changed

.github/workflows/db.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: python
2+
on:
3+
push:
4+
branches:
5+
- main
6+
pull_request:
7+
jobs:
8+
9+
build:
10+
name: test
11+
runs-on: ubuntu-latest
12+
13+
services:
14+
postgres:
15+
image: postgres:11
16+
env:
17+
POSTGRES_USER: postgres
18+
POSTGRES_PASSWORD: postgres
19+
POSTGRES_DB: postgres
20+
ports:
21+
- 5432:5432
22+
# needed because the postgres container does not provide a healthcheck
23+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
- uses: actions/setup-python@v4
28+
with:
29+
python-version: 3.11
30+
- name: Install python dependencies
31+
working-directory: ./examples/python
32+
run: |
33+
python -m pip install --upgrade pip
34+
python -m pip install -r requirements.txt
35+
- name: Test python code
36+
working-directory: ./examples/python
37+
env:
38+
PG_USER: postgres
39+
PG_HOST: localhost
40+
PG_DATABASE: postgres
41+
PG_PASSWORD: postgres
42+
PG_PORT: ${{ job.services.postgres.ports['5432'] }}
43+
run: |
44+
pytest src/tests

examples/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pytest~=6.2.2
2+
pytest-asyncio~=0.14.0
3+
psycopg2-binary~=2.8.6
4+
asyncpg~=0.21.0
5+
sqlalchemy==1.4.0

examples/sqlc.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
version: '2'
2+
plugins:
3+
- name: py
4+
wasm:
5+
url: https://downloads.sqlc.dev/plugin/sqlc-gen-python_1.1.0.wasm
6+
sha256: ef58f143a8c116781091441770c7166caaf361dd645f62b8f05f462e9f95c3b2
7+
sql:
8+
- schema: "src/authors/schema.sql"
9+
queries: "src/authors/query.sql"
10+
engine: postgresql
11+
codegen:
12+
- out: src/authors
13+
plugin: py
14+
options:
15+
package: authors
16+
emit_sync_querier: true
17+
emit_async_querier: true
18+
query_parameter_limit: 5
19+
- schema: "src/booktest/schema.sql"
20+
queries: "src/booktest/query.sql"
21+
engine: postgresql
22+
codegen:
23+
- out: src/booktest
24+
plugin: py
25+
options:
26+
package: booktest
27+
emit_async_querier: true
28+
query_parameter_limit: 5
29+
- schema: "src/jets/schema.sql"
30+
queries: "src/jets/query-building.sql"
31+
engine: postgresql
32+
codegen:
33+
- out: src/jets
34+
plugin: py
35+
options:
36+
package: jets
37+
emit_async_querier: true
38+
query_parameter_limit: 5
39+
- schema: "src/ondeck/schema"
40+
queries: "src/ondeck/query"
41+
engine: postgresql
42+
codegen:
43+
- out: src/ondeck
44+
plugin: py
45+
options:
46+
package: ondeck
47+
emit_async_querier: true
48+
query_parameter_limit: 5

examples/src/authors/__init__.py

Whitespace-only changes.

examples/src/authors/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
import dataclasses
5+
from typing import Optional
6+
7+
8+
@dataclasses.dataclass()
9+
class Author:
10+
id: int
11+
name: str
12+
bio: Optional[str]

examples/src/authors/query.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
# source: query.sql
5+
from typing import AsyncIterator, Iterator, Optional
6+
7+
import sqlalchemy
8+
import sqlalchemy.ext.asyncio
9+
10+
from authors import models
11+
12+
13+
CREATE_AUTHOR = """-- name: create_author \\:one
14+
INSERT INTO authors (
15+
name, bio
16+
) VALUES (
17+
:p1, :p2
18+
)
19+
RETURNING id, name, bio
20+
"""
21+
22+
23+
DELETE_AUTHOR = """-- name: delete_author \\:exec
24+
DELETE FROM authors
25+
WHERE id = :p1
26+
"""
27+
28+
29+
GET_AUTHOR = """-- name: get_author \\:one
30+
SELECT id, name, bio FROM authors
31+
WHERE id = :p1 LIMIT 1
32+
"""
33+
34+
35+
LIST_AUTHORS = """-- name: list_authors \\:many
36+
SELECT id, name, bio FROM authors
37+
ORDER BY name
38+
"""
39+
40+
41+
class Querier:
42+
def __init__(self, conn: sqlalchemy.engine.Connection):
43+
self._conn = conn
44+
45+
def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
46+
row = self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio}).first()
47+
if row is None:
48+
return None
49+
return models.Author(
50+
id=row[0],
51+
name=row[1],
52+
bio=row[2],
53+
)
54+
55+
def delete_author(self, *, id: int) -> None:
56+
self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})
57+
58+
def get_author(self, *, id: int) -> Optional[models.Author]:
59+
row = self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id}).first()
60+
if row is None:
61+
return None
62+
return models.Author(
63+
id=row[0],
64+
name=row[1],
65+
bio=row[2],
66+
)
67+
68+
def list_authors(self) -> Iterator[models.Author]:
69+
result = self._conn.execute(sqlalchemy.text(LIST_AUTHORS))
70+
for row in result:
71+
yield models.Author(
72+
id=row[0],
73+
name=row[1],
74+
bio=row[2],
75+
)
76+
77+
78+
class AsyncQuerier:
79+
def __init__(self, conn: sqlalchemy.ext.asyncio.AsyncConnection):
80+
self._conn = conn
81+
82+
async def create_author(self, *, name: str, bio: Optional[str]) -> Optional[models.Author]:
83+
row = (await self._conn.execute(sqlalchemy.text(CREATE_AUTHOR), {"p1": name, "p2": bio})).first()
84+
if row is None:
85+
return None
86+
return models.Author(
87+
id=row[0],
88+
name=row[1],
89+
bio=row[2],
90+
)
91+
92+
async def delete_author(self, *, id: int) -> None:
93+
await self._conn.execute(sqlalchemy.text(DELETE_AUTHOR), {"p1": id})
94+
95+
async def get_author(self, *, id: int) -> Optional[models.Author]:
96+
row = (await self._conn.execute(sqlalchemy.text(GET_AUTHOR), {"p1": id})).first()
97+
if row is None:
98+
return None
99+
return models.Author(
100+
id=row[0],
101+
name=row[1],
102+
bio=row[2],
103+
)
104+
105+
async def list_authors(self) -> AsyncIterator[models.Author]:
106+
result = await self._conn.stream(sqlalchemy.text(LIST_AUTHORS))
107+
async for row in result:
108+
yield models.Author(
109+
id=row[0],
110+
name=row[1],
111+
bio=row[2],
112+
)

examples/src/authors/query.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-- name: GetAuthor :one
2+
SELECT * FROM authors
3+
WHERE id = $1 LIMIT 1;
4+
5+
-- name: ListAuthors :many
6+
SELECT * FROM authors
7+
ORDER BY name;
8+
9+
-- name: CreateAuthor :one
10+
INSERT INTO authors (
11+
name, bio
12+
) VALUES (
13+
$1, $2
14+
)
15+
RETURNING *;
16+
17+
-- name: DeleteAuthor :exec
18+
DELETE FROM authors
19+
WHERE id = $1;

examples/src/authors/schema.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE authors (
2+
id BIGSERIAL PRIMARY KEY,
3+
name text NOT NULL,
4+
bio text
5+
);

examples/src/booktest/__init__.py

Whitespace-only changes.

examples/src/booktest/models.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Code generated by sqlc. DO NOT EDIT.
2+
# versions:
3+
# sqlc v1.23.0
4+
import dataclasses
5+
import datetime
6+
import enum
7+
from typing import List
8+
9+
10+
class BookType(str, enum.Enum):
11+
FICTION = "FICTION"
12+
NONFICTION = "NONFICTION"
13+
14+
15+
@dataclasses.dataclass()
16+
class Author:
17+
author_id: int
18+
name: str
19+
20+
21+
@dataclasses.dataclass()
22+
class Book:
23+
book_id: int
24+
author_id: int
25+
isbn: str
26+
book_type: BookType
27+
title: str
28+
year: int
29+
available: datetime.datetime
30+
tags: List[str]

0 commit comments

Comments
 (0)