Skip to content

Commit 715bb23

Browse files
Merge pull request #1 from cheese-drawer/v2
V2
2 parents cbece26 + 051b86c commit 715bb23

File tree

11 files changed

+88
-74
lines changed

11 files changed

+88
-74
lines changed

db_wrapper/model.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,21 @@
1313
)
1414
from uuid import UUID
1515

16+
# third party dependencies
17+
from pydantic import BaseModel
18+
1619
# internal dependency
1720
from .client import Client, sql
1821

1922

20-
class ModelData(TypedDict):
23+
class ModelData(BaseModel):
2124
"""Base interface for ModelData to be used in Model."""
2225

2326
# PENDS python 3.9 support in pylint
2427
# pylint: disable=inherit-non-class
2528
# pylint: disable=too-few-public-methods
2629

27-
_id: UUID
30+
id: UUID
2831

2932

3033
# Generic doesn't need a more descriptive name
@@ -65,7 +68,7 @@ async def one(self, item: T) -> T:
6568
columns: List[sql.Identifier] = []
6669
values: List[sql.Literal] = []
6770

68-
for column, value in item.items():
71+
for column, value in item.dict().items():
6972
values.append(sql.Literal(value))
7073

7174
columns.append(sql.Identifier(column))
@@ -100,7 +103,7 @@ async def one_by_id(self, id_value: str) -> T:
100103
query = sql.SQL(
101104
'SELECT * '
102105
'FROM {table} '
103-
'WHERE _id = {id_value};'
106+
'WHERE id = {id_value};'
104107
).format(
105108
table=self._table,
106109
id_value=sql.Literal(id_value)
@@ -152,7 +155,7 @@ def compose_changes(changes: Dict[str, Any]) -> sql.Composed:
152155
query = sql.SQL(
153156
'UPDATE {table} '
154157
'SET {changes} '
155-
'WHERE _id = {id_value} '
158+
'WHERE id = {id_value} '
156159
'RETURNING *;'
157160
).format(
158161
table=self._table,

example/example/example.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ async def create_a_model_record() -> UUID:
4141
4242
Create a new record using the default Model.create.one method.
4343
"""
44-
new_record: AModel = {
45-
'_id': uuid4(),
44+
new_record = AModel(**{
45+
'id': uuid4(),
4646
'string': 'some string',
4747
'integer': 1,
4848
'array': ['an', 'array', 'of', 'strings'],
49-
}
49+
})
5050

5151
await a_model.create.one(new_record)
5252

53-
return new_record['_id']
53+
return new_record.id
5454

5555

5656
async def read_a_model(id_value: UUID) -> AModel:
@@ -62,28 +62,31 @@ async def read_a_model(id_value: UUID) -> AModel:
6262

6363
async def create_extended_models() -> None:
6464
"""Show how using an extended Model can be the same as the defaults."""
65-
new_records: List[ExtendedModelData] = [{
66-
'_id': uuid4(),
65+
dicts = [{
66+
'id': uuid4(),
6767
'string': 'something',
6868
'integer': 1,
69-
'json': {'a': 1, 'b': 2, 'c': True}
69+
'data': {'a': 1, 'b': 2, 'c': True}
7070
}, {
71-
'_id': uuid4(),
71+
'id': uuid4(),
7272
'string': 'something',
7373
'integer': 1,
74-
'json': {'a': 1, 'b': 2, 'c': True}
74+
'data': {'a': 1, 'b': 2, 'c': True}
7575
}, {
76-
'_id': uuid4(),
76+
'id': uuid4(),
7777
'string': 'something',
7878
'integer': 1,
79-
'json': {'a': 1, 'b': 2, 'c': True}
79+
'data': {'a': 1, 'b': 2, 'c': True}
8080
}, {
81-
'_id': uuid4(),
81+
'id': uuid4(),
8282
'string': 'something',
8383
'integer': 1,
84-
'json': {'a': 1, 'b': 2, 'c': True}
84+
'data': {'a': 1, 'b': 2, 'c': True}
8585
}]
8686

87+
new_records: List[ExtendedModelData] = [
88+
ExtendedModelData(**record) for record in dicts]
89+
8790
# by looping over a list of records, you can use the default create.one
8891
# method to create each record as a separate transaction
8992
for record in new_records:
@@ -100,8 +103,14 @@ async def read_extended_models() -> List[ExtendedModelData]:
100103

101104
async def run() -> None:
102105
"""Show how to make a connection, execute queries, & disconnect."""
106+
107+
# First, have the client make a connection to the database
103108
await client.connect()
104109

110+
# Then, execute queries using the models that were initialized
111+
# with the client above.
112+
# Doing this inside a try/finally block allows client to gracefully
113+
# disconnect even when an exception is thrown.
105114
try:
106115
new_id = await create_a_model_record()
107116
created_a_model = await read_a_model(new_id)
@@ -110,6 +119,7 @@ async def run() -> None:
110119
finally:
111120
await client.disconnect()
112121

122+
# Print results to stdout
113123
print(json.dumps(created_a_model, cls=UUIDJsonEncoder))
114124
print(json.dumps(extended_models, cls=UUIDJsonEncoder))
115125

example/example/models/a_model.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CREATE TABLE IF NOT EXISTS "a_model" (
2-
"_id" uuid PRIMARY KEY,
2+
"id" uuid PRIMARY KEY,
33
"string" varchar(255),
44
"integer" smallint,
55
"array" varchar(255) []

example/example/models/extended_model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class ExtendedModelData(ModelData):
2323

2424
string: str
2525
integer: int
26-
json: Dict[str, Any]
26+
data: Dict[str, Any]
2727

2828

2929
class ExtendedCreator(Create[ExtendedModelData]):
@@ -34,10 +34,10 @@ class ExtendedCreator(Create[ExtendedModelData]):
3434
async def one(self, item: ExtendedModelData) -> ExtendedModelData:
3535
"""Override default Model.create.one method."""
3636
columns: List[sql.Identifier] = []
37-
values: List[sql.Identifier] = []
37+
values: List[sql.Literal] = []
3838

39-
for column, value in item.items():
40-
if column == 'json':
39+
for column, value in item.dict().items():
40+
if column == 'data':
4141
values.append(sql.Literal(json.dumps(value)))
4242
else:
4343
values.append(sql.Literal(value))
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
CREATE EXTENSION hstore;
22

33
CREATE TABLE IF NOT EXISTS "extended_model" (
4-
"_id" uuid PRIMARY KEY,
4+
"id" uuid PRIMARY KEY,
55
"string" varchar(255),
66
"integer" smallint,
7-
"json" jsonb
7+
"data" jsonb
88
);

example/requirements/prod.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
psycopg2-binary>=2.8.6,<3.0.0
2-
https://github.com/cheese-drawer/lib-python-db-wrapper/releases/download/0.1.0/db-wrapper-0.1.0.tar.gz
2+
https://github.com/cheese-drawer/lib-python-db-wrapper/releases/download/2.0.1/db_wrapper-2.0.1-py3-none-any.whl

requirements/prod.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
aiopg>=1.1.0,<2.0.0
2+
pydantic>=1.8.1,<2.0.0

scripts/test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function unit {
2929
echo ""
3030

3131
# run unit tests & save exit code
32-
cd tests
32+
cd test
3333
python -m unittest -b $@
3434
# save exit code from tests
3535
unit_result=$?

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="db_wrapper",
8-
version="0.1.4",
8+
version="2.0.1",
99
author="Andrew Chang-DeWitt",
1010
author_email="andrew@andrew-chang-dewitt.dev",
1111
description="Simple wrapper on aiopg to handle postgres connections & basic Models.",
@@ -17,6 +17,7 @@
1717
'db_wrapper': ['py.typed']},
1818
install_requires=[
1919
'aiopg>=1.1.0,<2.0.0',
20+
'pydantic>=1.8.1,<2.0.0',
2021
],
2122
classifiers=[
2223
"Programming Language :: Python :: 3",
File renamed without changes.

0 commit comments

Comments
 (0)