asyncpg-typed 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- asyncpg_typed-0.1.2/MANIFEST.in +1 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/PKG-INFO +39 -13
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/README.md +37 -11
- asyncpg_typed-0.1.2/asyncpg_typed/__init__.py +681 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/asyncpg_typed.egg-info/PKG-INFO +39 -13
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/asyncpg_typed.egg-info/SOURCES.txt +8 -5
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/pyproject.toml +1 -1
- asyncpg_typed-0.1.2/tests/__init__.py +0 -0
- asyncpg_typed-0.1.2/tests/connection.py +19 -0
- asyncpg_typed-0.1.2/tests/test_code.py +251 -0
- {asyncpg_typed-0.1.0/test → asyncpg_typed-0.1.2/tests}/test_data.py +189 -45
- {asyncpg_typed-0.1.0/test → asyncpg_typed-0.1.2/tests}/test_template.py +2 -13
- {asyncpg_typed-0.1.0/test → asyncpg_typed-0.1.2/tests}/test_vector.py +2 -12
- asyncpg_typed-0.1.0/asyncpg_typed/__init__.py +0 -827
- asyncpg_typed-0.1.0/test/test_code.py +0 -187
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/LICENSE +0 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/asyncpg_typed/py.typed +0 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/asyncpg_typed.egg-info/dependency_links.txt +0 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/asyncpg_typed.egg-info/requires.txt +0 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/asyncpg_typed.egg-info/top_level.txt +0 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/asyncpg_typed.egg-info/zip-safe +0 -0
- {asyncpg_typed-0.1.0 → asyncpg_typed-0.1.2}/setup.cfg +0 -0
- {asyncpg_typed-0.1.0/test → asyncpg_typed-0.1.2/tests}/test_type.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include tests *.py
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: asyncpg_typed
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Type-safe queries for asyncpg
|
|
5
5
|
Author-email: Levente Hunyadi <hunyadi@gmail.com>
|
|
6
6
|
Maintainer-email: Levente Hunyadi <hunyadi@gmail.com>
|
|
7
7
|
License-Expression: MIT
|
|
8
8
|
Project-URL: Homepage, https://github.com/hunyadi/asyncpg_typed
|
|
9
9
|
Project-URL: Source, https://github.com/hunyadi/asyncpg_typed
|
|
10
|
-
Keywords: asyncpg,typed,database-client
|
|
10
|
+
Keywords: asyncpg,typed,database-client,postgres
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
@@ -74,6 +74,25 @@ try:
|
|
|
74
74
|
|
|
75
75
|
finally:
|
|
76
76
|
await conn.close()
|
|
77
|
+
|
|
78
|
+
# create a list of data-class instances from a list of typed tuples
|
|
79
|
+
@dataclass
|
|
80
|
+
class DataObject:
|
|
81
|
+
boolean_value: bool
|
|
82
|
+
integer_value: int
|
|
83
|
+
string_value: str | None
|
|
84
|
+
|
|
85
|
+
# ✅ Valid initializer call
|
|
86
|
+
items = [DataObject(*row) for row in rows]
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class MismatchedObject:
|
|
90
|
+
boolean_value: bool
|
|
91
|
+
integer_value: int
|
|
92
|
+
string_value: str
|
|
93
|
+
|
|
94
|
+
# ⚠️ Argument of type "int | None" cannot be assigned to parameter "integer_value" of type "int" in function "__init__"; "None" is not assignable to "int"
|
|
95
|
+
items = [MismatchedObject(*row) for row in rows]
|
|
77
96
|
```
|
|
78
97
|
|
|
79
98
|
|
|
@@ -85,19 +104,21 @@ Instantiate a SQL object with the `sql` function:
|
|
|
85
104
|
|
|
86
105
|
```python
|
|
87
106
|
def sql(
|
|
88
|
-
stmt:
|
|
107
|
+
stmt: LiteralString | string.templatelib.Template,
|
|
89
108
|
*,
|
|
90
|
-
args: None | type[
|
|
91
|
-
resultset: None | type[
|
|
109
|
+
args: None | type[tuple[P1, P2]] | type[tuple[P1, P2, P3]] | ... = None,
|
|
110
|
+
resultset: None | type[tuple[R1, R2]] | type[tuple[R1, R2, R3]] | ... = None,
|
|
111
|
+
arg: None | type[P] = None,
|
|
112
|
+
result: None | type[R] = None,
|
|
92
113
|
) -> _SQL: ...
|
|
93
114
|
```
|
|
94
115
|
|
|
95
|
-
The parameter `stmt` represents a SQL expression, either as a
|
|
116
|
+
The parameter `stmt` represents a SQL expression, either as a literal string or a template (i.e. a *t-string*).
|
|
96
117
|
|
|
97
118
|
If the expression is a string, it can have PostgreSQL parameter placeholders such as `$1`, `$2` or `$3`:
|
|
98
119
|
|
|
99
120
|
```python
|
|
100
|
-
|
|
121
|
+
"INSERT INTO table_name (col_1, col_2, col_3) VALUES ($1, $2, $3);"
|
|
101
122
|
```
|
|
102
123
|
|
|
103
124
|
If the expression is a *t-string*, it can have replacement fields that evaluate to integers:
|
|
@@ -106,11 +127,10 @@ If the expression is a *t-string*, it can have replacement fields that evaluate
|
|
|
106
127
|
t"INSERT INTO table_name (col_1, col_2, col_3) VALUES ({1}, {2}, {3});"
|
|
107
128
|
```
|
|
108
129
|
|
|
109
|
-
The parameters `args` and `resultset` take a
|
|
130
|
+
The parameters `args` and `resultset` take a `tuple` of several types `Px` or `Rx`, each of which may be any of the following:
|
|
110
131
|
|
|
111
132
|
* (required) simple type
|
|
112
133
|
* optional simple type (`T | None`)
|
|
113
|
-
* `tuple` of several (required or optional) simple types.
|
|
114
134
|
|
|
115
135
|
Simple types include:
|
|
116
136
|
|
|
@@ -124,6 +144,7 @@ Simple types include:
|
|
|
124
144
|
* `str`
|
|
125
145
|
* `bytes`
|
|
126
146
|
* `uuid.UUID`
|
|
147
|
+
* a user-defined class that derives from `StrEnum`
|
|
127
148
|
|
|
128
149
|
Types are grouped together with `tuple`:
|
|
129
150
|
|
|
@@ -131,11 +152,11 @@ Types are grouped together with `tuple`:
|
|
|
131
152
|
tuple[bool, int, str | None]
|
|
132
153
|
```
|
|
133
154
|
|
|
134
|
-
Passing a simple type
|
|
155
|
+
The parameters `arg` and `result` take a single type `P` or `R`. Passing a simple type (e.g. `type[T]`) directly via `arg` and `result` is for convenience, and is equivalent to passing a one-element tuple of the same simple type (i.e. `type[tuple[T]]`) via `args` and `resultset`.
|
|
135
156
|
|
|
136
157
|
The number of types in `args` must correspond to the number of query parameters. (This is validated on calling `sql(...)` for the *t-string* syntax.) The number of types in `resultset` must correspond to the number of columns returned by the query.
|
|
137
158
|
|
|
138
|
-
Both `args` and `resultset` types must be compatible with their corresponding PostgreSQL query parameter types and resultset column types, respectively. The following table shows the mapping between PostgreSQL and Python types.
|
|
159
|
+
Both `args` and `resultset` types must be compatible with their corresponding PostgreSQL query parameter types and resultset column types, respectively. The following table shows the mapping between PostgreSQL and Python types. When there are multiple options separated by a slash, either of the types can be specified as a source or target type.
|
|
139
160
|
|
|
140
161
|
| PostgreSQL type | Python type |
|
|
141
162
|
| ----------------- | ------------------ |
|
|
@@ -152,13 +173,18 @@ Both `args` and `resultset` types must be compatible with their corresponding Po
|
|
|
152
173
|
| `timetz` | `time` (tz) |
|
|
153
174
|
| `timestamp` | `datetime` (naive) |
|
|
154
175
|
| `timestamptz` | `datetime` (tz) |
|
|
176
|
+
| `interval` | `timedelta` |
|
|
155
177
|
| `char(N)` | `str` |
|
|
156
178
|
| `varchar(N)` | `str` |
|
|
157
179
|
| `text` | `str` |
|
|
158
180
|
| `bytea` | `bytes` |
|
|
159
|
-
| `json` | `str`
|
|
160
|
-
| `jsonb` | `str`
|
|
181
|
+
| `json` | `str`/`JsonType` |
|
|
182
|
+
| `jsonb` | `str`/`JsonType` |
|
|
183
|
+
| `xml` | `str` |
|
|
161
184
|
| `uuid` | `UUID` |
|
|
185
|
+
| enumeration | `E: StrEnum` |
|
|
186
|
+
|
|
187
|
+
PostgreSQL types `json` and `jsonb` are [returned by asyncpg](https://magicstack.github.io/asyncpg/current/usage.html#type-conversion) as Python type `str`. However, if we specify the union type `JsonType` in `args` or `resultset`, the JSON string is parsed as if by calling `json.loads()`. (`JsonType` is defined in the module `asyncpg_typed`.) If the library `orjson` is present, its faster routines are invoked instead of the slower standard library implementation in the module `json`.
|
|
162
188
|
|
|
163
189
|
### Using a SQL object
|
|
164
190
|
|
|
@@ -36,6 +36,25 @@ try:
|
|
|
36
36
|
|
|
37
37
|
finally:
|
|
38
38
|
await conn.close()
|
|
39
|
+
|
|
40
|
+
# create a list of data-class instances from a list of typed tuples
|
|
41
|
+
@dataclass
|
|
42
|
+
class DataObject:
|
|
43
|
+
boolean_value: bool
|
|
44
|
+
integer_value: int
|
|
45
|
+
string_value: str | None
|
|
46
|
+
|
|
47
|
+
# ✅ Valid initializer call
|
|
48
|
+
items = [DataObject(*row) for row in rows]
|
|
49
|
+
|
|
50
|
+
@dataclass
|
|
51
|
+
class MismatchedObject:
|
|
52
|
+
boolean_value: bool
|
|
53
|
+
integer_value: int
|
|
54
|
+
string_value: str
|
|
55
|
+
|
|
56
|
+
# ⚠️ Argument of type "int | None" cannot be assigned to parameter "integer_value" of type "int" in function "__init__"; "None" is not assignable to "int"
|
|
57
|
+
items = [MismatchedObject(*row) for row in rows]
|
|
39
58
|
```
|
|
40
59
|
|
|
41
60
|
|
|
@@ -47,19 +66,21 @@ Instantiate a SQL object with the `sql` function:
|
|
|
47
66
|
|
|
48
67
|
```python
|
|
49
68
|
def sql(
|
|
50
|
-
stmt:
|
|
69
|
+
stmt: LiteralString | string.templatelib.Template,
|
|
51
70
|
*,
|
|
52
|
-
args: None | type[
|
|
53
|
-
resultset: None | type[
|
|
71
|
+
args: None | type[tuple[P1, P2]] | type[tuple[P1, P2, P3]] | ... = None,
|
|
72
|
+
resultset: None | type[tuple[R1, R2]] | type[tuple[R1, R2, R3]] | ... = None,
|
|
73
|
+
arg: None | type[P] = None,
|
|
74
|
+
result: None | type[R] = None,
|
|
54
75
|
) -> _SQL: ...
|
|
55
76
|
```
|
|
56
77
|
|
|
57
|
-
The parameter `stmt` represents a SQL expression, either as a
|
|
78
|
+
The parameter `stmt` represents a SQL expression, either as a literal string or a template (i.e. a *t-string*).
|
|
58
79
|
|
|
59
80
|
If the expression is a string, it can have PostgreSQL parameter placeholders such as `$1`, `$2` or `$3`:
|
|
60
81
|
|
|
61
82
|
```python
|
|
62
|
-
|
|
83
|
+
"INSERT INTO table_name (col_1, col_2, col_3) VALUES ($1, $2, $3);"
|
|
63
84
|
```
|
|
64
85
|
|
|
65
86
|
If the expression is a *t-string*, it can have replacement fields that evaluate to integers:
|
|
@@ -68,11 +89,10 @@ If the expression is a *t-string*, it can have replacement fields that evaluate
|
|
|
68
89
|
t"INSERT INTO table_name (col_1, col_2, col_3) VALUES ({1}, {2}, {3});"
|
|
69
90
|
```
|
|
70
91
|
|
|
71
|
-
The parameters `args` and `resultset` take a
|
|
92
|
+
The parameters `args` and `resultset` take a `tuple` of several types `Px` or `Rx`, each of which may be any of the following:
|
|
72
93
|
|
|
73
94
|
* (required) simple type
|
|
74
95
|
* optional simple type (`T | None`)
|
|
75
|
-
* `tuple` of several (required or optional) simple types.
|
|
76
96
|
|
|
77
97
|
Simple types include:
|
|
78
98
|
|
|
@@ -86,6 +106,7 @@ Simple types include:
|
|
|
86
106
|
* `str`
|
|
87
107
|
* `bytes`
|
|
88
108
|
* `uuid.UUID`
|
|
109
|
+
* a user-defined class that derives from `StrEnum`
|
|
89
110
|
|
|
90
111
|
Types are grouped together with `tuple`:
|
|
91
112
|
|
|
@@ -93,11 +114,11 @@ Types are grouped together with `tuple`:
|
|
|
93
114
|
tuple[bool, int, str | None]
|
|
94
115
|
```
|
|
95
116
|
|
|
96
|
-
Passing a simple type
|
|
117
|
+
The parameters `arg` and `result` take a single type `P` or `R`. Passing a simple type (e.g. `type[T]`) directly via `arg` and `result` is for convenience, and is equivalent to passing a one-element tuple of the same simple type (i.e. `type[tuple[T]]`) via `args` and `resultset`.
|
|
97
118
|
|
|
98
119
|
The number of types in `args` must correspond to the number of query parameters. (This is validated on calling `sql(...)` for the *t-string* syntax.) The number of types in `resultset` must correspond to the number of columns returned by the query.
|
|
99
120
|
|
|
100
|
-
Both `args` and `resultset` types must be compatible with their corresponding PostgreSQL query parameter types and resultset column types, respectively. The following table shows the mapping between PostgreSQL and Python types.
|
|
121
|
+
Both `args` and `resultset` types must be compatible with their corresponding PostgreSQL query parameter types and resultset column types, respectively. The following table shows the mapping between PostgreSQL and Python types. When there are multiple options separated by a slash, either of the types can be specified as a source or target type.
|
|
101
122
|
|
|
102
123
|
| PostgreSQL type | Python type |
|
|
103
124
|
| ----------------- | ------------------ |
|
|
@@ -114,13 +135,18 @@ Both `args` and `resultset` types must be compatible with their corresponding Po
|
|
|
114
135
|
| `timetz` | `time` (tz) |
|
|
115
136
|
| `timestamp` | `datetime` (naive) |
|
|
116
137
|
| `timestamptz` | `datetime` (tz) |
|
|
138
|
+
| `interval` | `timedelta` |
|
|
117
139
|
| `char(N)` | `str` |
|
|
118
140
|
| `varchar(N)` | `str` |
|
|
119
141
|
| `text` | `str` |
|
|
120
142
|
| `bytea` | `bytes` |
|
|
121
|
-
| `json` | `str`
|
|
122
|
-
| `jsonb` | `str`
|
|
143
|
+
| `json` | `str`/`JsonType` |
|
|
144
|
+
| `jsonb` | `str`/`JsonType` |
|
|
145
|
+
| `xml` | `str` |
|
|
123
146
|
| `uuid` | `UUID` |
|
|
147
|
+
| enumeration | `E: StrEnum` |
|
|
148
|
+
|
|
149
|
+
PostgreSQL types `json` and `jsonb` are [returned by asyncpg](https://magicstack.github.io/asyncpg/current/usage.html#type-conversion) as Python type `str`. However, if we specify the union type `JsonType` in `args` or `resultset`, the JSON string is parsed as if by calling `json.loads()`. (`JsonType` is defined in the module `asyncpg_typed`.) If the library `orjson` is present, its faster routines are invoked instead of the slower standard library implementation in the module `json`.
|
|
124
150
|
|
|
125
151
|
### Using a SQL object
|
|
126
152
|
|