Skip to content

Commit 6be61e5

Browse files
committed
chore(python): implement logic for accessing PostgreSQL and make a simplest GET query work
Part of #16 Relate to #15
1 parent 4a9a191 commit 6be61e5

File tree

5 files changed

+68
-6
lines changed

5 files changed

+68
-6
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ Generates the endpoints (or a whole app) from a mapping (SQL query -> URL)
4848
| -----------| ----------------------------| ---------------------------| --------- |
4949
| JavaScript | `npx query2app --lang js` | [`app.js`](examples/js/app.js)<br/>[`routes.js`](examples/js/routes.js)<br/>[`package.json`](examples/js/package.json) | Web: [`express`](https://www.npmjs.com/package/express), [`body-parser`](https://www.npmjs.com/package/body-parser)<br>Database: [`mysql`](https://www.npmjs.com/package/mysql) |
5050
| Golang | `npx query2app --lang go` | [`app.go`](examples/go/app.go)<br/>[`routes.go`](examples/go/routes.go)<br/>[`go.mod`](examples/go/go.mod) | Web: [`go-chi/chi`](https://github.com/go-chi/chi)<br/>Database: [`go-sql-driver/mysql`](https://github.com/go-sql-driver/mysql), [`jmoiron/sqlx`](https://github.com/jmoiron/sqlx) |
51-
| Python | `npx query2app --lang python` | [`app.py`](examples/python/app.py)<br/>[`routes.py`](examples/python/routes.py)<br/>[`requirements.txt`](examples/python/requirements.txt) | Web: [FastAPI](https://github.com/tiangolo/fastapi), [Uvicorn](https://www.uvicorn.org) |
51+
| Python | `npx query2app --lang python` | [`app.py`](examples/python/app.py)<br/>[`routes.py`](examples/python/routes.py)<br/>[`requirements.txt`](examples/python/requirements.txt) | Web: [FastAPI](https://github.com/tiangolo/fastapi), [Uvicorn](https://www.uvicorn.org)<br/>Database: [](https://pypi.org/project/psycopg2/) |
5252

5353
1. Run the application
5454
| Language | Commands to run the application |
5555
| -----------| --------------------------------|
5656
| JavaScript | <pre>$ npm install<br/>$ export DB_NAME=my-db DB_USER=my-user DB_PASSWORD=my-password<br/>$ npm start</pre> |
5757
| Golang | <pre>$ go run *.go</pre>or<pre>$ go build -o app<br/>$ ./app</pre> |
58-
| Python | <pre>$ pip install -r requirements.txt<br/>$ uvicorn app:app</pre> |
58+
| Python | <pre>$ pip install -r requirements.txt<br/>$ export DB_NAME=my-db DB_USER=my-user DB_PASSWORD=my-password<br/>$ uvicorn app:app</pre> |
5959

6060
---
6161
:bulb: **NOTE**

examples/python/requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
fastapi===0.83.0
22
uvicorn==0.18.3
3+
psycopg2-binary==2.9.3

examples/python/routes.py

+42-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,42 @@
1+
import os
2+
import psycopg2
3+
14
from fastapi import APIRouter
25

36
router = APIRouter()
47

58

69
@router.get('/v1/categories/count')
710
def get_v1_categories_count():
8-
pass
11+
conn = psycopg2.connect(
12+
database = os.getenv('DB_NAME'),
13+
user = os.getenv('DB_USER'),
14+
password = os.getenv('DB_PASSWORD'),
15+
host = os.getenv('DB_HOST', 'localhost'),
16+
port = 5432)
17+
try:
18+
with conn:
19+
with conn.cursor() as cur:
20+
cur.execute('SELECT COUNT(*) AS counter FROM categories')
21+
return cur.fetchone()[0]
22+
finally:
23+
conn.close()
924

1025
@router.get('/v1/collections/:collectionId/categories/count')
1126
def get_v1_collections_collection_id_categories_count():
12-
pass
27+
conn = psycopg2.connect(
28+
database = os.getenv('DB_NAME'),
29+
user = os.getenv('DB_USER'),
30+
password = os.getenv('DB_PASSWORD'),
31+
host = os.getenv('DB_HOST', 'localhost'),
32+
port = 5432)
33+
try:
34+
with conn:
35+
with conn.cursor() as cur:
36+
cur.execute('SELECT COUNT(DISTINCT s.category_id) AS counter FROM collections_series cs JOIN series s ON s.id = cs.series_id WHERE cs.collection_id = :collectionId')
37+
return cur.fetchone()[0]
38+
finally:
39+
conn.close()
1340

1441
@router.get('/v1/categories')
1542
def get_list_v1_categories():
@@ -21,7 +48,19 @@ def post_v1_categories():
2148

2249
@router.get('/v1/categories/:categoryId')
2350
def get_v1_categories_category_id():
24-
pass
51+
conn = psycopg2.connect(
52+
database = os.getenv('DB_NAME'),
53+
user = os.getenv('DB_USER'),
54+
password = os.getenv('DB_PASSWORD'),
55+
host = os.getenv('DB_HOST', 'localhost'),
56+
port = 5432)
57+
try:
58+
with conn:
59+
with conn.cursor() as cur:
60+
cur.execute('SELECT id , name , name_ru , slug FROM categories WHERE id = :categoryId')
61+
return cur.fetchone()[0]
62+
finally:
63+
conn.close()
2564

2665
@router.put('/v1/categories/:categoryId')
2766
def put_v1_categories_category_id():

src/templates/requirements.txt.ejs

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
fastapi===0.83.0
22
uvicorn==0.18.3
3+
psycopg2-binary==2.9.3

src/templates/routes.py.ejs

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import os
2+
import psycopg2
3+
14
from fastapi import APIRouter
25

36
router = APIRouter()
@@ -14,14 +17,32 @@ endpoints.forEach(function(endpoint) {
1417
1518
endpoint.methods.forEach(function(method) {
1619
const pythonMethodName = generate_method_name(method.name, path)
20+
const sql = formatQuery(method.query)
1721
1822
if (method.name === 'get' || method.name === 'get_list') {
1923
%>
2024
@router.get('<%- path %>')
2125
def <%- pythonMethodName %>():
26+
<% if (method.name === 'get') { -%>
27+
conn = psycopg2.connect(
28+
database = os.getenv('DB_NAME'),
29+
user = os.getenv('DB_USER'),
30+
password = os.getenv('DB_PASSWORD'),
31+
host = os.getenv('DB_HOST', 'localhost'),
32+
port = 5432)
33+
try:
34+
with conn:
35+
with conn.cursor() as cur:
36+
cur.execute('<%- sql %>')
37+
return cur.fetchone()[0]
38+
finally:
39+
conn.close()
40+
<%
41+
} else {
42+
-%>
2243
pass
2344
<%
24-
45+
}
2546
}
2647
if (method.name === 'post') {
2748
%>

0 commit comments

Comments
 (0)