Skip to content

Commit e638cde

Browse files
committed
Added performance improvement
1 parent fc67e74 commit e638cde

File tree

5 files changed

+122
-43
lines changed

5 files changed

+122
-43
lines changed

docs/components/results.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ async def main() -> None:
3333
list_dict_result: List[Dict[str, Any]] = query_result.result()
3434

3535
# Result as tuple
36-
list_tuple_result: List[Tuple[str, typing.Any], ...] = query_result.result(
36+
list_tuple_result: List[Tuple[t.Any, ...]] = query_result.result(
3737
as_tuple=True,
3838
)
3939
```
@@ -100,7 +100,7 @@ async def main() -> None:
100100
dict_result: Dict[str, Any] = query_result.result()
101101

102102
# Result as tuple
103-
tuple_result: Tuple[str, typing.Any] = query_result.result(
103+
tuple_result: Tuple[typing.Any, ...] = query_result.result(
104104
as_tuple=True,
105105
)
106106
```

perf_test.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import uvicorn
2+
from psqlpy import ConnectionPool
3+
4+
from panther import Panther
5+
from panther.app import API
6+
from panther.configs import config
7+
from panther.events import Event
8+
from panther.response import Response
9+
10+
11+
@Event.startup
12+
async def create_connection_pool():
13+
config.connection_pool = ConnectionPool(
14+
dsn="postgres://postgres:postgres@localhost:5432/postgres",
15+
max_db_pool_size=10,
16+
)
17+
18+
19+
@Event.shutdown
20+
async def close_connection_pool():
21+
config.connection_pool.close()
22+
23+
24+
@API()
25+
async def pg_pool_example():
26+
connection = await config.connection_pool.connection()
27+
query_result = await connection.execute(
28+
"SELECT * FROM users",
29+
)
30+
return Response(data=query_result.result())
31+
32+
33+
app = Panther(__name__, configs=__name__, urls={'/': pg_pool_example})
34+
35+
if __name__ == "__main__":
36+
uvicorn.run(app)

python/tests/conftest.py

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -134,69 +134,76 @@ async def create_default_data_for_tests(
134134
table_name: str,
135135
number_database_records: int,
136136
) -> AsyncGenerator[None, None]:
137-
connection = await psql_pool.connection()
138-
await connection.execute(
139-
f"CREATE TABLE {table_name} (id SERIAL, name VARCHAR(255))",
140-
)
141-
142-
for table_id in range(1, number_database_records + 1):
143-
new_name = random_string()
137+
async with psql_pool.acquire() as connection:
144138
await connection.execute(
145-
querystring=f"INSERT INTO {table_name} VALUES ($1, $2)",
146-
parameters=[table_id, new_name],
139+
f"CREATE TABLE {table_name} (id SERIAL, name VARCHAR(255))",
147140
)
141+
142+
for table_id in range(1, number_database_records + 1):
143+
new_name = random_string()
144+
await connection.execute(
145+
querystring=f"INSERT INTO {table_name} VALUES ($1, $2)",
146+
parameters=[table_id, new_name],
147+
)
148+
148149
yield
149-
await connection.execute(
150-
f"DROP TABLE {table_name}",
151-
)
150+
151+
async with psql_pool.acquire() as connection:
152+
await connection.execute(
153+
f"DROP TABLE {table_name}",
154+
)
152155

153156

154157
@pytest.fixture
155158
async def create_table_for_listener_tests(
156159
psql_pool: ConnectionPool,
157160
listener_table_name: str,
158161
) -> AsyncGenerator[None, None]:
159-
connection = await psql_pool.connection()
160-
await connection.execute(
161-
f"CREATE TABLE {listener_table_name}"
162-
f"(id SERIAL, payload VARCHAR(255),"
163-
f"channel VARCHAR(255), process_id INT)",
164-
)
162+
async with psql_pool.acquire() as connection:
163+
await connection.execute(
164+
f"CREATE TABLE {listener_table_name}"
165+
f"(id SERIAL, payload VARCHAR(255),"
166+
f"channel VARCHAR(255), process_id INT)",
167+
)
165168

166169
yield
167-
await connection.execute(
168-
f"DROP TABLE {listener_table_name}",
169-
)
170+
171+
async with psql_pool.acquire() as connection:
172+
await connection.execute(
173+
f"DROP TABLE {listener_table_name}",
174+
)
170175

171176

172177
@pytest.fixture
173178
async def create_table_for_map_parameters_test(
174179
psql_pool: ConnectionPool,
175180
map_parameters_table_name: str,
176181
) -> AsyncGenerator[None, None]:
177-
connection = await psql_pool.connection()
178-
await connection.execute(
179-
f"CREATE TABLE {map_parameters_table_name}"
180-
"(id SERIAL, name VARCHAR(255),surname VARCHAR(255), age SMALLINT)",
181-
)
182+
async with psql_pool.acquire() as connection:
183+
await connection.execute(
184+
f"CREATE TABLE {map_parameters_table_name}"
185+
"(id SERIAL, name VARCHAR(255),surname VARCHAR(255), age SMALLINT)",
186+
)
182187

183188
yield
184-
await connection.execute(
185-
f"DROP TABLE {map_parameters_table_name}",
186-
)
189+
190+
async with psql_pool.acquire() as connection:
191+
await connection.execute(
192+
f"DROP TABLE {map_parameters_table_name}",
193+
)
187194

188195

189196
@pytest.fixture
190197
async def test_cursor(
191198
psql_pool: ConnectionPool,
192199
table_name: str,
193200
) -> AsyncGenerator[Cursor, None]:
194-
connection = await psql_pool.connection()
195-
transaction = connection.transaction()
196-
await transaction.begin()
197-
cursor = transaction.cursor(
198-
querystring=f"SELECT * FROM {table_name}",
199-
)
200-
await cursor.start()
201-
yield cursor
202-
await transaction.commit()
201+
async with psql_pool.acquire() as connection:
202+
transaction = connection.transaction()
203+
await transaction.begin()
204+
cursor = transaction.cursor(
205+
querystring=f"SELECT * FROM {table_name}",
206+
)
207+
await cursor.start()
208+
yield cursor
209+
await transaction.commit()

src/connection/impls.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,31 @@ impl PSQLPyConnection {
367367
Ok(PSQLDriverPyQueryResult::new(result))
368368
}
369369

370+
/// Execute raw querystring without parameters.
371+
///
372+
/// # Errors
373+
/// May return error if there is some problem with DB communication.
374+
pub async fn execute_no_params(
375+
&self,
376+
querystring: String,
377+
prepared: Option<bool>,
378+
) -> PSQLPyResult<PSQLDriverPyQueryResult> {
379+
let prepared = prepared.unwrap_or(true);
380+
let result = if prepared {
381+
self.query(&querystring, &[]).await
382+
} else {
383+
self.query_typed(&querystring, &[]).await
384+
};
385+
386+
let return_result = result.map_err(|err| {
387+
RustPSQLDriverError::ConnectionExecuteError(format!(
388+
"Cannot execute query, error - {err}"
389+
))
390+
})?;
391+
392+
Ok(PSQLDriverPyQueryResult::new(return_result))
393+
}
394+
370395
/// Execute raw query with parameters.
371396
///
372397
/// # Errors

src/driver/connection.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,13 @@ impl Connection {
237237

238238
if let Some(db_client) = db_client {
239239
let read_conn_g = db_client.read().await;
240-
let res = read_conn_g.execute(querystring, parameters, prepared).await;
241-
return res;
240+
return {
241+
if parameters.is_some() {
242+
read_conn_g.execute(querystring, parameters, prepared).await
243+
} else {
244+
read_conn_g.execute_no_params(querystring, prepared).await
245+
}
246+
};
242247
}
243248

244249
Err(RustPSQLDriverError::ConnectionClosedError)
@@ -318,7 +323,13 @@ impl Connection {
318323

319324
if let Some(db_client) = db_client {
320325
let read_conn_g = db_client.read().await;
321-
return read_conn_g.execute(querystring, parameters, prepared).await;
326+
return {
327+
if parameters.is_some() {
328+
read_conn_g.execute(querystring, parameters, prepared).await
329+
} else {
330+
read_conn_g.execute_no_params(querystring, prepared).await
331+
}
332+
};
322333
}
323334

324335
Err(RustPSQLDriverError::ConnectionClosedError)

0 commit comments

Comments
 (0)