Skip to content

Commit 17a78aa

Browse files
author
Eugene Shershen
committed
init
1 parent e310794 commit 17a78aa

File tree

7 files changed

+110
-28
lines changed

7 files changed

+110
-28
lines changed

.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.pre-commit-config.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
exclude: (alembic|build|dist|docker|esign|kubernetes|migrations)
2+
3+
default_language_version:
4+
python: python3.13
5+
6+
repos:
7+
- repo: https://github.com/pre-commit/pre-commit-hooks
8+
rev: v4.4.0
9+
hooks:
10+
- id: end-of-file-fixer
11+
- id: trailing-whitespace
12+
13+
args: [ --fix, --unsafe-fixes ]
14+
15+
- repo: https://github.com/asottile/pyupgrade
16+
rev: v2.28.0
17+
hooks:
18+
- id: pyupgrade
19+
args:
20+
- --py37-plus
21+
- repo: https://github.com/myint/autoflake
22+
rev: v1.4
23+
hooks:
24+
- id: autoflake
25+
args:
26+
- --in-place
27+
- --remove-all-unused-imports
28+
- --expand-star-imports
29+
- --remove-duplicate-keys
30+
- --remove-unused-variables
31+
- repo: https://github.com/PyCQA/isort
32+
rev: 5.12.0
33+
hooks:
34+
- id: isort
35+
- repo: https://github.com/psf/black
36+
rev: 22.3.0
37+
hooks:
38+
- id: black
39+
- repo: https://github.com/PyCQA/flake8
40+
rev: 5.0.4
41+
hooks:
42+
- id: flake8
43+
args:
44+
- --max-line-length=79
45+
- --ignore=E203, E501, W503
46+
- repo: https://github.com/pre-commit/mirrors-mypy
47+
rev: v0.982
48+
hooks:
49+
- id: mypy
50+
additional_dependencies:
51+
- pydantic
52+
- types-ujson

psqlpy_sqlalchemy/connection.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,20 @@ def execute(
2828
if parameters is None:
2929
self._result = self._psqlpy_connection.fetch(query)
3030
else:
31-
# Convert parameters to psqlpy format if needed
3231
if isinstance(parameters, (list, tuple)):
33-
# Convert positional parameters to named parameters
34-
# This is a simplified conversion - in practice, you might need more
35-
# sophisticated handling
36-
param_dict = {f"param_{i}": val for i, val in enumerate(parameters)}
37-
query = self._convert_positional_to_named(query, len(parameters))
38-
self._result = self._psqlpy_connection.fetch(query, param_dict)
32+
param_dict = {
33+
f"param_{i}": val for i, val in enumerate(parameters)
34+
}
35+
query = self._convert_positional_to_named(
36+
query, len(parameters)
37+
)
38+
self._result = self._psqlpy_connection.fetch(
39+
query, param_dict
40+
)
3941
else:
40-
self._result = self._psqlpy_connection.fetch(query, parameters)
42+
self._result = self._psqlpy_connection.fetch(
43+
query, parameters
44+
)
4145

4246
# Process the result
4347
if self._result:
@@ -66,11 +70,11 @@ def execute(
6670
except Exception as e:
6771
raise self._convert_exception(e)
6872

69-
def executemany(self, query: str, parameters_list: List[Union[dict, list, tuple]]):
73+
def executemany(
74+
self, query: str, parameters_list: List[Union[dict, list, tuple]]
75+
):
7076
"""Execute a query multiple times with different parameters"""
7177
try:
72-
# For executemany, we'll execute each set of parameters individually
73-
# In a more sophisticated implementation, you might use psqlpy's batch execution
7478
total_rowcount = 0
7579
for parameters in parameters_list:
7680
self.execute(query, parameters)
@@ -133,10 +137,10 @@ def close(self):
133137
self.rowcount = -1
134138
self.description = None
135139

136-
def _convert_positional_to_named(self, query: str, param_count: int) -> str:
137-
"""Convert positional parameters (?) to named parameters (%(param_N)s)"""
138-
# This is a simplified implementation
139-
# In practice, you'd need more sophisticated SQL parsing
140+
def _convert_positional_to_named(
141+
self, query: str, param_count: int
142+
) -> str:
143+
"Convert positional parameters (?) to named parameters (%(param_N)s)"
140144
result = query
141145
for i in range(param_count):
142146
result = result.replace("?", f"%(param_{i})s", 1)

psqlpy_sqlalchemy/dialect.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ def import_dbapi(cls):
4949
"""Import the psqlpy module as DBAPI"""
5050
return PsqlpyDBAPI()
5151

52-
def create_connect_args(self, url: URL) -> Tuple[List[Any], Dict[str, Any]]:
52+
def create_connect_args(
53+
self, url: URL
54+
) -> Tuple[List[Any], Dict[str, Any]]:
5355
"""Create connection arguments from SQLAlchemy URL"""
5456
opts = {}
5557

@@ -73,7 +75,9 @@ def create_connect_args(self, url: URL) -> Tuple[List[Any], Dict[str, Any]]:
7375

7476
# Map common PostgreSQL connection parameters
7577
if key == "sslmode":
76-
opts["ssl_mode"] = getattr(psqlpy.SslMode, value.upper(), None)
78+
opts["ssl_mode"] = getattr(
79+
psqlpy.SslMode, value.upper(), None
80+
)
7781
elif key == "application_name":
7882
opts["application_name"] = value
7983
elif key == "connect_timeout":

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ where = ["."]
5555
include = ["psqlpy_sqlalchemy*"]
5656

5757
[tool.black]
58-
line-length = 88
58+
line-length = 79
5959
target-version = ['py38']
6060

6161
[tool.isort]
6262
profile = "black"
63-
line_length = 88
63+
line_length = 79
6464

6565
[tool.mypy]
6666
python_version = "3.9"

tests/test_dbapi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ def test_exception_hierarchy(self):
3939

4040
for exc_name in exceptions:
4141
self.assertTrue(
42-
hasattr(self.dbapi, exc_name), f"Missing DBAPI exception: {exc_name}"
42+
hasattr(self.dbapi, exc_name),
43+
f"Missing DBAPI exception: {exc_name}",
4344
)
4445
exc_class = getattr(self.dbapi, exc_name)
4546
self.assertTrue(

tests/test_dialect.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@
55

66
import unittest
77

8-
from sqlalchemy import Column, Integer, MetaData, String, Table, create_engine, text
8+
from sqlalchemy import (
9+
Column,
10+
Integer,
11+
MetaData,
12+
String,
13+
Table,
14+
create_engine,
15+
text,
16+
)
917
from sqlalchemy.schema import CreateTable
1018

1119

@@ -37,19 +45,23 @@ def test_connection_string_parsing(self):
3745
"""Test connection string parsing"""
3846
try:
3947
self.engine = create_engine(
40-
"postgresql+psqlpy://testuser:testpass@localhost:5432/testdb?sslmode=require"
48+
"postgresql+psqlpy://testuser:testpass@localhost:5432/testdb?sslmode=require" # noqa
4149
)
4250

4351
# Test create_connect_args
44-
args, kwargs = self.engine.dialect.create_connect_args(self.engine.url)
52+
args, kwargs = self.engine.dialect.create_connect_args(
53+
self.engine.url
54+
)
4555

4656
self.assertIsInstance(args, list)
4757
self.assertIsInstance(kwargs, dict)
4858

4959
# Check expected connection parameters
5060
expected_keys = ["host", "port", "db_name", "username", "password"]
5161
for key in expected_keys:
52-
self.assertIn(key, kwargs, f"Missing connection parameter: {key}")
62+
self.assertIn(
63+
key, kwargs, f"Missing connection parameter: {key}"
64+
)
5365

5466
# Verify specific values
5567
self.assertEqual(kwargs["host"], "localhost")
@@ -124,7 +136,8 @@ def test_dbapi_interface(self):
124136

125137
for exc_name in exceptions:
126138
self.assertTrue(
127-
hasattr(dbapi, exc_name), f"Missing DBAPI exception: {exc_name}"
139+
hasattr(dbapi, exc_name),
140+
f"Missing DBAPI exception: {exc_name}",
128141
)
129142

130143
except Exception as e:
@@ -137,13 +150,13 @@ def test_mock_connection(self):
137150
"postgresql+psqlpy://user:password@localhost/test"
138151
)
139152

140-
# This will fail because we don't have a real database,
141-
# but we can test that the connection creation process starts correctly
142153
try:
143154
connection = self.engine.connect()
144155
# If we get here, connection succeeded unexpectedly
145156
connection.close()
146-
self.fail("Connection succeeded unexpectedly without a real database")
157+
self.fail(
158+
"Connection succeeded unexpectedly without a real database"
159+
)
147160
except Exception:
148161
# This is expected - we don't have a real database
149162
# The test passes if an exception is raised

0 commit comments

Comments
 (0)