Skip to content

Commit 1b20b95

Browse files
authored
Add SQLAlchemy 2 support (#46)
* Add SQLAlchemy 2 support * Fix linting * update 2.0.x matrix scripts
1 parent b3c6367 commit 1b20b95

File tree

4 files changed

+38
-26
lines changed

4 files changed

+38
-26
lines changed

.github/workflows/test.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,19 @@ jobs:
6161
ENGINE: 'sqlite:///test.db?check_same_thread=False'
6262
STORAGE_PROVIDER: 'LOCAL'
6363
LOCAL_PATH: '/tmp/storage'
64-
run: hatch run test:all
64+
run: hatch run test:run
6565
- name: Test Local Storage provider & postgresql
6666
env:
6767
ENGINE: 'postgresql+psycopg2://username:password@localhost:5432/test_db'
6868
STORAGE_PROVIDER: 'LOCAL'
6969
LOCAL_PATH: '/tmp/storage'
70-
run: hatch run test:all
70+
run: hatch run test:run
7171
- name: Test Local Storage provider & mysql
7272
env:
7373
ENGINE: 'mysql+pymysql://username:password@localhost:3306/test_db'
7474
STORAGE_PROVIDER: 'LOCAL'
7575
LOCAL_PATH: '/tmp/storage'
76-
run: hatch run test:all
76+
run: hatch run test:run
7777
- name: Test Minio Storage provider & sqlite memory
7878
env:
7979
ENGINE: 'sqlite:///:memory:?check_same_thread=False'
@@ -83,7 +83,7 @@ jobs:
8383
MINIO_HOST: 'localhost'
8484
MINIO_PORT: 9000
8585
MINIO_SECURE: false
86-
run: hatch run test:all
86+
run: hatch run test:run
8787
- name: Coverage Report
8888
run: hatch run test:cov
8989
- name: Upload coverage

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ poetry.lock
77
dist
88
htmlcov
99
*.egg-info
10-
.coverage
10+
.coverage*
1111
coverage.xml
1212
site
1313
*.db

pyproject.toml

+23-9
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ classifiers = [
3030
"Topic :: Database :: Database Engines/Servers",
3131
]
3232
dependencies = [
33-
"SQLAlchemy >=1.4, <1.5",
33+
"SQLAlchemy >=1.4, <2.1",
3434
"apache-libcloud >=3.6, <3.8",
3535
]
3636
dynamic = ["version"]
@@ -44,16 +44,15 @@ Changelog = "https://jowilf.github.io/sqlalchemy-file/changelog/"
4444
[project.optional-dependencies]
4545
test = [
4646
"pytest >=7.2.0, <7.3.0",
47-
"mypy ==0.991",
48-
"ruff ==0.0.215",
49-
"black ==22.12.0",
50-
"coverage >=7.0.0, <7.1.0",
47+
"mypy ==1.0.1",
48+
"ruff ==0.0.253",
49+
"black ==23.1.0",
50+
"coverage >=7.0.0, <7.3.0",
5151
"fasteners ==0.18",
5252
"PyMySQL[rsa] >=1.0.2, <1.1.0",
5353
"psycopg2-binary >=2.9.5, <3.0.0",
5454
"Pillow >=9.4.0, <9.5.0",
55-
"sqlmodel ==0.0.8",
56-
"python-multipart ==0.0.5",
55+
"python-multipart ==0.0.6",
5756
"fastapi >=0.92, <0.93",
5857
"Flask >=2.2, <2.3",
5958
"Flask-SQLAlchemy >=3.0,<3.1"
@@ -63,7 +62,7 @@ doc = [
6362
"mkdocstrings[python] >=0.19.0, <0.21.0"
6463
]
6564
dev = [
66-
"pre-commit >=2.20.0, <3.0.0",
65+
"pre-commit >=2.20.0, <4.0.0",
6766
"uvicorn >=0.20.0, <0.21.0",
6867
]
6968

@@ -88,13 +87,27 @@ lint = [
8887
"ruff sqlalchemy_file tests",
8988
"black . --check"
9089
]
91-
all = "coverage run -m pytest tests"
90+
run = "coverage run -m pytest tests"
9291
cov = [
9392
"coverage combine",
9493
"coverage report --show-missing",
9594
"coverage xml"
9695
]
9796

97+
[[tool.hatch.envs.test.matrix]]
98+
sqla_version = ["1.4.x", "2.0.x"]
99+
100+
[tool.hatch.envs.test.overrides]
101+
matrix.sqla_version.dependencies = [
102+
{ value = "SQLAlchemy >=2.0, <2.1", if = ["2.0.x"] },
103+
{ value = "SQLAlchemy >=1.4, <1.5", if = ["1.4.x"] },
104+
{ value = "sqlmodel ==0.0.8", if = ["1.4.x"] },
105+
]
106+
matrix.sqla_version.scripts = [
107+
{ key = "run", value = 'coverage run -m pytest tests --ignore=tests/test_sqlmodel.py', if = ["2.0.x"] },
108+
{ key = "cov", value = '', if = ["2.0.x"] },
109+
]
110+
98111
[tool.hatch.envs.docs]
99112
features = [
100113
"doc",
@@ -136,6 +149,7 @@ known-third-party = ["sqlalchemy_file"]
136149

137150
[tool.mypy]
138151
strict = true
152+
warn_unused_ignores = false
139153

140154
[tool.hatch.build.targets.wheel]
141155
[tool.hatch.build.targets.sdist]

sqlalchemy_file/types.py

+10-12
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,7 @@ def add_old_files_to_session(cls, session: Session, paths: List[str]) -> None:
190190
session._old_files.update(paths) # type: ignore
191191

192192
@classmethod
193-
def extract_files_from_history(
194-
cls, data: List[Union[MutableList[File], File]]
195-
) -> List[str]:
193+
def extract_files_from_history(cls, data: Union[Tuple[()], List[Any]]) -> List[str]:
196194
paths = []
197195
for item in data:
198196
if isinstance(item, list):
@@ -202,7 +200,7 @@ def extract_files_from_history(
202200
return paths
203201

204202
@classmethod
205-
def _mapper_configured(cls, mapper: Mapper, class_: Any) -> None:
203+
def _mapper_configured(cls, mapper: Mapper, class_: Any) -> None: # type: ignore[type-arg]
206204
"""Detect and listen all class with FileField Column"""
207205
for mapper_property in mapper.iterate_properties:
208206
if isinstance(mapper_property, ColumnProperty) and isinstance(
@@ -238,7 +236,7 @@ def _after_soft_rollback(cls, session: Session, _: SessionTransaction) -> None:
238236
cls.clear_session(session)
239237

240238
@classmethod
241-
def _after_delete(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
239+
def _after_delete(cls, mapper: Mapper, _: Connection, obj: Any) -> None: # type: ignore[type-arg]
242240
"""
243241
After delete mark all linked files as old in order to delete
244242
them when after session is committed
@@ -256,7 +254,7 @@ def _after_delete(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
256254
)
257255

258256
@classmethod
259-
def _after_update(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
257+
def _after_update(cls, mapper: Mapper, _: Connection, obj: Any) -> None: # type: ignore[type-arg]
260258
"""
261259
After update, mark all edited files as old
262260
in order to delete them when after session is committed
@@ -269,7 +267,7 @@ def _after_update(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
269267
)
270268

271269
@classmethod
272-
def _before_update(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
270+
def _before_update(cls, mapper: Mapper, _: Connection, obj: Any) -> None: # type: ignore[type-arg]
273271
"""
274272
Before updating values, validate and save files. For multiple fields,
275273
mark all removed files as old, as _removed attribute will be
@@ -292,7 +290,7 @@ def _before_update(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
292290
cls.add_old_files_to_session(session, [f["path"] for f in _removed])
293291

294292
@classmethod
295-
def _before_insert(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
293+
def _before_insert(cls, mapper: Mapper, _: Connection, obj: Any) -> None: # type: ignore[type-arg]
296294
"""Before inserting values, mark all created files as new. They will be
297295
automatically removed when session rollback"""
298296

@@ -308,7 +306,7 @@ def _before_insert(cls, mapper: Mapper, _: Connection, obj: Any) -> None:
308306

309307
@classmethod
310308
def prepare_file_attr(
311-
cls, mapper: Mapper, obj: Any, key: str
309+
cls, mapper: Mapper, obj: Any, key: str # type: ignore[type-arg]
312310
) -> Tuple[bool, Union[File, List[File]]]:
313311
"""
314312
Prepare file before saved to database, convert bytes and string,
@@ -320,7 +318,7 @@ def prepare_file_attr(
320318
or when new items is added for multiple field"""
321319
changed = False
322320

323-
column_type = mapper.attrs.get(key).columns[0].type
321+
column_type = mapper.attrs.get(key).columns[0].type # type: ignore[misc,union-attr]
324322
assert isinstance(column_type, FileField)
325323
upload_type = column_type.upload_type
326324

@@ -351,8 +349,8 @@ def prepare_file_attr(
351349

352350
@classmethod
353351
def setup(cls) -> None:
354-
event.listen(orm.mapper, "mapper_configured", cls._mapper_configured)
355-
event.listen(orm.mapper, "after_configured", cls._after_configured)
352+
event.listen(orm.Mapper, "mapper_configured", cls._mapper_configured)
353+
event.listen(orm.Mapper, "after_configured", cls._after_configured)
356354
event.listen(Session, "after_commit", cls._after_commit)
357355
event.listen(Session, "after_soft_rollback", cls._after_soft_rollback)
358356

0 commit comments

Comments
 (0)