You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If looking for a different release version, just replace the two instances of `0.1.2` in the command with the version number you need.
15
+
If looking for a different release version, just replace the two instances of `2.1.0` in the command with the version number you need.
16
16
17
17
## Usage
18
18
19
-
This library uses a fairly simple API to manage asynchronously connecting to, executing queries on, & disconnecting from a PostgresQL database.
20
-
Additionally, it includes a very simple Model abstraction to help with defining queries for a given model & managing separation of concerns in your application.
19
+
This library uses a fairly simple API to manage connecting to, executing queries on, & disconnecting from a PostgresQL database, in both synchronous & asynchronous APIs.
20
+
Additionally, it includes a very simple Model abstraction to help with declaring data types, enforcing types at runtime, defining queries for a given model, & managing separation of concerns in your application.
21
21
22
-
### Example`Client`
22
+
### Example: Clients
23
23
24
24
Intializing a database `Client` & executing a query begins with defining a connection & giving it to `Client` on intialization:
25
25
26
26
```python
27
-
from db_wrapper import ConnectionParameters
27
+
from db_wrapper import ConnectionParameters, AsyncClient
28
28
29
29
connection_parameters = ConnectionParameters(
30
30
host='localhost',
31
31
user='postgres',
32
32
password='postgres',
33
33
database='postgres')
34
-
client =Client(connection_parameters)
34
+
client =AsyncClient(connection_parameters)
35
35
```
36
36
37
-
From there, you need to tell the client to connect using `Client.connect()` before you can execute any queries.
37
+
From there, you need to tell the client to connect using `client.connect()` before you can execute any queries.
38
38
This method is asynchronous though, so you need to supply an async/await runtime.
39
39
40
40
```python
@@ -45,7 +45,7 @@ import asyncio
45
45
46
46
asyncdefa_query() -> None:
47
47
# we'll come back to this part
48
-
# just know that it usins async/await to call Client.execute_and_return
48
+
# just know that it uses async/await to call Client.execute_and_return
49
49
result =await client.execute_and_return(query)
50
50
51
51
# do something with the result...
@@ -78,14 +78,42 @@ async def a_query() -> None:
78
78
79
79
```
80
80
81
-
### Example: `Model`
81
+
Alternatively, everything can also be done synchronously, using an API that is almost exactly the same.
82
+
Simply drop the async/await keywords & skip the async event loop, then proceed in exactly the same fashion:
82
83
83
-
Using `Model` isn't necessary at all, you can just interact directly with the `Client` instance using it's `execute` & `execute_and_return` methods to execute SQL queries as needed.
84
-
`Model` may be helpful in managing your separation of concerns by giving you a single place to define queries related to a given data model in your database.
85
-
Additionally, `Model` will be helpful in defining types, if you're using mypy to check your types in development.
84
+
```python
85
+
from db_wrapper import ConnectionParameters, SyncClient
86
+
87
+
connection_parameters = ConnectionParameters(
88
+
host='localhost',
89
+
user='postgres',
90
+
password='postgres',
91
+
database='postgres')
92
+
client = SyncClient(connection_parameters)
93
+
94
+
95
+
defa_query() -> None:
96
+
query ='SELECT table_name' \
97
+
'FROM information_schema.tables' \
98
+
'WHERE table_schema = public'
99
+
result = client.execute_and_return(query)
100
+
101
+
assert result[0] =='postgres'
102
+
103
+
104
+
client.connect()
105
+
a_query()
106
+
client.disconnect()
107
+
```
108
+
109
+
### Example: Models
110
+
111
+
Using `AsyncModel` or `SyncModel` isn't necessary at all, you can just interact directly with the Client instance using it's `execute` & `execute_and_return` methods to execute SQL queries as needed.
112
+
A Model may be helpful in managing your separation of concerns by giving you a single place to define queries related to a given data model in your database.
113
+
Additionally, `Model` will be helpful in defining types, if you're using mypy to check your types in development, & in enforcing types at runtime using pydantic..
86
114
It has no concept of types at runtime, however, & cannot be relied upon to constrain data types & shapes during runtime.
87
115
88
-
A `Model` instance has 4 properties, corresponding with each of the CRUD operations: `create`, `read`, `update`, & `delete`.
116
+
A Model instance has 4 properties, corresponding with each of the CRUD operations: `create`, `read`, `update`, & `delete`.
89
117
Each CRUD property has one built-in method to handle the simplest of queries for you already (create one record, read one record by id, update one record by id, & delete one record by id).
90
118
91
119
Using a model requires defining it's expected type (using `ModelData`), initializing a new instance, then calling the query methods as needed.
@@ -102,35 +130,36 @@ class AModel(ModelData):
102
130
a_boolean_value: bool
103
131
```
104
132
105
-
Subclassing `ModelData` is important because `Model` expects all records to be constrained to a dictionary containing at least one field labeled `_id` & constrained to the UUID type. This means the above `AModel` will contain records that look like the following dictionary in python:
133
+
Subclassing `ModelData` is important because `Model` expects all records to be constrained to a Subclass of `ModelData`, containing least one property labeled `_id` constrained to the UUID type.
134
+
This means the above `AModel` will contain records that look like the following dictionary in python:
106
135
107
136
```python
108
-
a_model_result= {
137
+
a_model_result.dict() == {
109
138
_id: UUID(...),
110
139
a_string_value: 'some string',
111
140
a_number_value: 12345,
112
141
a_boolean_value: True
113
142
}
114
143
```
115
144
116
-
Then to initialize your `Model` with your new expected type, simply initialize `Model`by passing `AModel` as a type parameter, a `Client` instance, & the name of the table this `Model` will be represented on:
145
+
Then to initialize your Model with your new expected type, simply initialize `AsyncModel` or `SyncModel`by passing `AModel` as a type parameter, a matching Client instance, & the name of the table this Model will be represented on:
Finally, using your `ExtendedModel` is simple, just initialize the class with a `Client` instance & use it just as you would your previous `Model` instance, `a_model`:
234
+
Finally, using your `ExtendedModel` is simple, just initialize the class with a `AsyncClient` instance & use it just as you would your previous `AsyncModel` instance, `a_model`:
0 commit comments