Skip to content

Commit 901c644

Browse files
authored
Merge pull request #92 from psqlpy-python/feature/add_explicit_array_types
Added explicit array types
2 parents e7c0b58 + f1cbe23 commit 901c644

File tree

11 files changed

+1687
-53
lines changed

11 files changed

+1687
-53
lines changed

docs/.vuepress/sidebar.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export default sidebar({
3838
collapsible: true,
3939
children: [
4040
"supported_types",
41+
"array_types",
4142
"extra_types",
4243
"advanced_type_usage",
4344
]
@@ -75,5 +76,10 @@ export default sidebar({
7576
prefix: "/benchmarks",
7677
link: "/benchmarks.md"
7778
},
79+
{
80+
text: "FAQ",
81+
prefix: "/faq",
82+
link: "/faq.md"
83+
},
7884
],
7985
});

docs/components/connection.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,10 @@ async def main() -> None:
184184
- `isolation_level`: level of isolation. Default how it is in PostgreSQL.
185185
- `read_variant`: configure read variant of the transaction. Default how it is in PostgreSQL.
186186
- `deferrable`: configure deferrable of the transaction. Default how it is in PostgreSQL.
187+
- `synchronous_commit`: configure [synchronous_commit](https://postgresqlco.nf/doc/en/param/synchronous_commit/) option for transaction. Default how it is in PostgreSQL.
187188

188189
```python
189-
from psqlpy import IsolationLevel, ReadVariant
190+
from psqlpy import IsolationLevel, ReadVariant, SynchronousCommit
190191

191192
async def main() -> None:
192193
...
@@ -195,6 +196,7 @@ async def main() -> None:
195196
isolation_level=IsolationLevel.Serializable,
196197
read_variant=ReadVariant.ReadWrite,
197198
deferrable=True,
199+
synchronous_commit=SynchronousCommit.On,
198200
)
199201
```
200202

docs/components/connection_pool.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ Parameters must be passed as list after querystring.
192192
::: caution
193193
You must use `ConnectionPool.execute` method in high-load production code wisely!
194194
It pulls connection from the pool each time you execute query.
195-
Preferable way to execute statements with [Connection](./../../introduction/components/connection.md) or [Transaction](./../../introduction/components/transaction.md)
195+
Preferable way to execute statements with [Connection](./../components/connection.md) or [Transaction](./../components/transaction.md)
196196
:::
197197

198198
```python

docs/faq.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
title: Frequently asked questions
3+
---
4+
5+
Here you can find most common questions and problems.
6+
7+
### LIMIT of OFFSET isn't working
8+
The main problem is PostgreSQL expects `LIMIT` and `OFFSET` to be BIGINT type but when you pass python `int` into `parameters` it converts to `INTEGER`.
9+
10+
#### Problem and Solution:
11+
```python
12+
from psqlpy import ConnectionPool
13+
from psqlpy.extra_types import BigInt
14+
15+
# --- Incorrect ---
16+
async def main() -> None:
17+
pool = ConnectionPool()
18+
await pool.execute(
19+
querystring="SELECT * FROM users LIMIT $1 OFFSET $2",
20+
parameters=[10, 100],
21+
)
22+
23+
24+
# --- Correct ---
25+
async def main() -> None:
26+
pool = ConnectionPool()
27+
await pool.execute(
28+
querystring="SELECT * FROM users LIMIT $1 OFFSET $2",
29+
parameters=[BigInt(10), BigInt(100)],
30+
)
31+
```
32+
33+
### WHERE IN clause isn't working
34+
Instead of using `WHERE <field> IN ()` clause you must use `WHERE <field> = ANY()`.
35+
36+
#### Problem and Solution:
37+
```python
38+
from psqlpy import ConnectionPool
39+
40+
# --- Incorrect ---
41+
async def main() -> None:
42+
pool = ConnectionPool()
43+
await pool.execute(
44+
querystring="SELECT * FROM users WHERE id IN ($1)",
45+
parameters=[
46+
(1, 2, 3),
47+
],
48+
)
49+
50+
51+
# --- Correct ---
52+
async def main() -> None:
53+
pool = ConnectionPool()
54+
await pool.execute(
55+
querystring="SELECT * FROM users WHERE id = ANY($1)",
56+
parameters=[
57+
(1, 2, 3),
58+
],
59+
)
60+
```
61+
62+
### Wrong binary data
63+
64+
Example error: `binary data has array element type 1043 (character varying) instead of expected 25 (text)`.
65+
66+
This exception tells you that you use wrong data type and you need to specify types explicitly.
67+
68+
For example, when we want to make `WHERE` clause with `ANY` and string values, we need to use `TextArray`, see example below:
69+
70+
#### Problem and Solution:
71+
```python
72+
from psqlpy import ConnectionPool
73+
from psqlpy.extra_types import TextArray
74+
75+
# --- Incorrect ---
76+
async def main() -> None:
77+
pool = ConnectionPool()
78+
await pool.execute(
79+
querystring="SELECT * FROM users WHERE name = ANY($1)",
80+
parameters=[
81+
["Foo", "Bar", "Cafe"],
82+
],
83+
)
84+
85+
86+
# --- Correct ---
87+
async def main() -> None:
88+
pool = ConnectionPool()
89+
await pool.execute(
90+
querystring="SELECT * FROM users WHERE name = ANY($1)",
91+
parameters=[
92+
TextArray(["Foo", "Bar", "Cafe"]),
93+
],
94+
)
95+
```
96+
97+
### Cannot insert empty ARRAY
98+
99+
To insert empty array use explicit [Array Type](./usage/types/array_types.md).
100+
101+
#### Problem and Solution:
102+
Let's assume that we have table `arr_table` with field `some_array` of `VARCHAR ARRAY` type.
103+
The main problem that we cannot determine the type of the empty sequence passed from Python side.
104+
```python
105+
from psqlpy import ConnectionPool
106+
from psqlpy.extra_types import VarCharArray
107+
108+
# --- Incorrect ---
109+
async def main() -> None:
110+
pool = ConnectionPool()
111+
await pool.execute(
112+
querystring="INSERT INTO arr_table (some_array) VALUES ($1)",
113+
parameters=[
114+
[],
115+
],
116+
)
117+
118+
119+
# --- Correct ---
120+
async def main() -> None:
121+
pool = ConnectionPool()
122+
await pool.execute(
123+
querystring="INSERT INTO arr_table (some_array) VALUES ($1)",
124+
parameters=[
125+
VarCharArray([]),
126+
],
127+
)
128+
```

docs/usage/types/array_types.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: Array Types
3+
---
4+
For type safety and better performance we have predefined array types.
5+
6+
| PSQLPy Array Type | PostgreSQL Array Type |
7+
| :---: | :---: |
8+
| BoolArray | BOOLEAN ARRAY |
9+
| UUIDArray | UUID ARRAY |
10+
| VarCharArray | VarChar ARRAY |
11+
| TextArray | Text ARRAY |
12+
| Int16Array | INT2 ARRAY |
13+
| Int32Array | INT4 ARRAY |
14+
| Int64Array | INT8 ARRAY |
15+
| Float32Array | FLOAT4 ARRAY |
16+
| Float64Array | FLOAT8 ARRAY |
17+
| MoneyArray | MONEY ARRAY |
18+
| IpAddressArray | INET ARRAY |
19+
| JSONBArray | JSONB ARRAY |
20+
| JSONArray | JSON ARRAY |
21+
| DateArray | DATE ARRAY |
22+
| TimeArray | TIME ARRAY |
23+
| DateTimeArray | TIMESTAMP ARRAY |
24+
| DateTimeTZArray | TIMESTAMPTZ ARRAY |
25+
| MacAddr6Array | MACADDR ARRAY |
26+
| MacAddr8Array | MACADDR8 ARRAY |
27+
| NumericArray | NUMERIC ARRAY |
28+
| PointArray | POINT ARRAY |
29+
| BoxArray | BOX ARRAY |
30+
| PathArray | PATH ARRAY |
31+
| LineArray | LINE ARRAY |
32+
| LsegArray | LSEG ARRAY |
33+
| CircleArray | CIRCLE ARRAY |
34+
35+
### Example:
36+
37+
```python
38+
from psqlpy import ConnectionPool
39+
from psqlpy.extra_types import TextArray
40+
41+
42+
async def main() -> None:
43+
pool = ConnectionPool()
44+
result = await pool.execute(
45+
querystring="SELECT * FROM users WHERE id = ANY($1)",
46+
parameters=[
47+
TextArray([1, 2, 3]),
48+
]
49+
)
50+
```

docs/usage/types/supported_types.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ DECIMAL PostgreSQL type isn't supported, use NUMERIC instead.
5050
## Array Type
5151

5252
You can make arrays with any type of `Simple Type`s.
53+
For better performance and type safety we recommend to use predefined [Array Types](./array_types.md).
5354

5455
#### Example:
5556
```sql

0 commit comments

Comments
 (0)