Skip to content

Commit 84dde9f

Browse files
committed
add psycopg 2, psycopg3, mysqlclient connection options to the query class. add postgres db for benchmarks
1 parent caa5b1b commit 84dde9f

14 files changed

Lines changed: 1537 additions & 755 deletions

CUSTOM_CONNECTIONS.md

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
# Custom Database Connections
2+
3+
Djazzle supports using your own database connections instead of Django's default connection. This is useful when you want to:
4+
5+
- Use a different database than your Django settings
6+
- Manage connection pools yourself
7+
- Use native async database drivers
8+
- Integrate with existing database connection code
9+
10+
## Supported Connection Types
11+
12+
- **Django connections** (default) - Standard Django database connections
13+
- **psycopg2** - PostgreSQL driver (sync only)
14+
- **psycopg3** - Modern PostgreSQL driver (sync and async)
15+
- **mysqlclient** - MySQL driver (MySQLdb - sync only)
16+
- **pymysql** - Pure Python MySQL driver (sync only)
17+
- **aiomysql** - Async MySQL driver (async only)
18+
- **asyncmy** - Another async MySQL driver (async only)
19+
20+
## Usage Examples
21+
22+
### Django Connection (Default)
23+
24+
```python
25+
from djazzle import DjazzleQuery, TableFromModel
26+
from myapp.models import User
27+
28+
users = TableFromModel(User)
29+
30+
# Uses Django's default connection
31+
db = DjazzleQuery()
32+
results = db.select().from_(users)()
33+
```
34+
35+
### Custom Django Connection
36+
37+
```python
38+
from django.db import connections
39+
from djazzle import DjazzleQuery, TableFromModel
40+
from myapp.models import User
41+
42+
users = TableFromModel(User)
43+
44+
# Use a specific Django connection from settings
45+
db = DjazzleQuery(conn=connections['other_db'])
46+
results = db.select().from_(users)()
47+
```
48+
49+
### psycopg2 (PostgreSQL - Sync Only)
50+
51+
```python
52+
import psycopg2
53+
from djazzle import DjazzleQuery, TableFromModel
54+
from myapp.models import User
55+
56+
users = TableFromModel(User)
57+
58+
# Create your own psycopg2 connection
59+
conn = psycopg2.connect("dbname=mydb user=myuser password=mypass")
60+
61+
# Pass it to Djazzle
62+
db = DjazzleQuery(conn=conn)
63+
results = db.select().from_(users)()
64+
65+
conn.close()
66+
```
67+
68+
### psycopg3 (PostgreSQL - Sync)
69+
70+
```python
71+
import psycopg
72+
from djazzle import DjazzleQuery, TableFromModel
73+
from myapp.models import User
74+
75+
users = TableFromModel(User)
76+
77+
# Create your own psycopg3 connection
78+
conn = psycopg.connect("dbname=mydb user=myuser password=mypass")
79+
80+
# Pass it to Djazzle
81+
db = DjazzleQuery(conn=conn)
82+
results = db.select().from_(users)()
83+
84+
conn.close()
85+
```
86+
87+
### psycopg3 (PostgreSQL - Async)
88+
89+
```python
90+
import asyncio
91+
import psycopg
92+
from djazzle import DjazzleQuery, TableFromModel
93+
from myapp.models import User
94+
95+
users = TableFromModel(User)
96+
97+
async def main():
98+
# Create async connection using psycopg3
99+
async with await psycopg.AsyncConnection.connect(
100+
"dbname=mydb user=myuser password=mypass"
101+
) as conn:
102+
# Pass it to Djazzle
103+
db = DjazzleQuery(conn=conn)
104+
105+
# Use await syntax for queries
106+
results = await db.select().from_(users)
107+
print(results)
108+
109+
asyncio.run(main())
110+
```
111+
112+
### mysqlclient (MySQLdb)
113+
114+
```python
115+
import MySQLdb
116+
from djazzle import DjazzleQuery, TableFromModel
117+
from myapp.models import User
118+
119+
users = TableFromModel(User)
120+
121+
# Create your own MySQLdb connection
122+
conn = MySQLdb.connect(
123+
host="localhost",
124+
user="myuser",
125+
password="mypass",
126+
database="mydb"
127+
)
128+
129+
# Pass it to Djazzle
130+
db = DjazzleQuery(conn=conn)
131+
results = db.select().from_(users)()
132+
133+
conn.close()
134+
```
135+
136+
### pymysql
137+
138+
```python
139+
import pymysql
140+
from djazzle import DjazzleQuery, TableFromModel
141+
from myapp.models import User
142+
143+
users = TableFromModel(User)
144+
145+
# Create your own pymysql connection
146+
conn = pymysql.connect(
147+
host="localhost",
148+
user="myuser",
149+
password="mypass",
150+
database="mydb"
151+
)
152+
153+
# Pass it to Djazzle
154+
db = DjazzleQuery(conn=conn)
155+
results = db.select().from_(users)()
156+
157+
conn.close()
158+
```
159+
160+
### aiomysql (Async)
161+
162+
```python
163+
import asyncio
164+
import aiomysql
165+
from djazzle import DjazzleQuery, TableFromModel
166+
from myapp.models import User
167+
168+
users = TableFromModel(User)
169+
170+
async def main():
171+
# Create async connection
172+
conn = await aiomysql.connect(
173+
host="localhost",
174+
user="myuser",
175+
password="mypass",
176+
db="mydb"
177+
)
178+
179+
# Pass it to Djazzle
180+
db = DjazzleQuery(conn=conn)
181+
182+
# Use await syntax for queries
183+
results = await db.select().from_(users)
184+
print(results)
185+
186+
conn.close()
187+
188+
asyncio.run(main())
189+
```
190+
191+
### asyncmy (Async)
192+
193+
```python
194+
import asyncio
195+
import asyncmy
196+
from djazzle import DjazzleQuery, TableFromModel
197+
from myapp.models import User
198+
199+
users = TableFromModel(User)
200+
201+
async def main():
202+
# Create async connection
203+
conn = await asyncmy.connect(
204+
host="localhost",
205+
user="myuser",
206+
password="mypass",
207+
database="mydb"
208+
)
209+
210+
# Pass it to Djazzle
211+
db = DjazzleQuery(conn=conn)
212+
213+
# Use await syntax for queries
214+
results = await db.select().from_(users)
215+
print(results)
216+
217+
await conn.close()
218+
219+
asyncio.run(main())
220+
```
221+
222+
## Connection Pooling
223+
224+
When using custom connections, you're responsible for managing connection pooling:
225+
226+
### psycopg with Connection Pool
227+
228+
```python
229+
from psycopg_pool import ConnectionPool
230+
from djazzle import DjazzleQuery, TableFromModel
231+
from myapp.models import User
232+
233+
users = TableFromModel(User)
234+
235+
# Create a connection pool
236+
pool = ConnectionPool("dbname=mydb user=myuser password=mypass")
237+
238+
# Get a connection from the pool
239+
with pool.connection() as conn:
240+
db = DjazzleQuery(conn=conn)
241+
results = db.select().from_(users)()
242+
243+
pool.close()
244+
```
245+
246+
### aiomysql with Connection Pool
247+
248+
```python
249+
import asyncio
250+
import aiomysql
251+
from djazzle import DjazzleQuery, TableFromModel
252+
from myapp.models import User
253+
254+
users = TableFromModel(User)
255+
256+
async def main():
257+
# Create async connection pool
258+
pool = await aiomysql.create_pool(
259+
host="localhost",
260+
user="myuser",
261+
password="mypass",
262+
db="mydb",
263+
minsize=1,
264+
maxsize=10
265+
)
266+
267+
# Get connection from pool
268+
async with pool.acquire() as conn:
269+
db = DjazzleQuery(conn=conn)
270+
results = await db.select().from_(users)
271+
print(results)
272+
273+
pool.close()
274+
await pool.wait_closed()
275+
276+
asyncio.run(main())
277+
```
278+
279+
## Important Notes
280+
281+
1. **Django Models**: Djazzle still uses Django models for schema information via `TableFromModel`, but you can execute queries against any compatible database connection.
282+
283+
2. **Async vs Sync**:
284+
- Sync connections (psycopg, mysqlclient, pymysql) must use the sync call syntax: `query()`
285+
- Async connections (aiomysql, asyncmy) must use await syntax: `await query`
286+
- Mixing sync and async will raise an error
287+
288+
3. **Model Instantiation**: When using `.as_model()`, the database alias will be:
289+
- For Django connections: uses the actual connection alias
290+
- For custom connections: defaults to `'default'`
291+
292+
4. **Connection Management**: You're responsible for:
293+
- Opening and closing connections
294+
- Managing connection pools
295+
- Handling connection errors
296+
- Transaction management
297+
298+
5. **Database Compatibility**: Djazzle generates SQL that should work across PostgreSQL, MySQL, and SQLite, but some features (like `RETURNING` clause) are PostgreSQL-specific.

0 commit comments

Comments
 (0)