Skip to content

Commit a419f3c

Browse files
authored
Merge branch 'main' into main
2 parents e52fef5 + c702e2e commit a419f3c

File tree

8 files changed

+358
-43
lines changed

8 files changed

+358
-43
lines changed

.github/workflows/smokeshow.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,15 @@ env:
1313

1414
jobs:
1515
smokeshow:
16-
if: ${{ github.event.workflow_run.conclusion == 'success' }}
1716
runs-on: ubuntu-latest
1817
steps:
1918
- uses: actions/checkout@v6
2019
- uses: actions/setup-python@v6
2120
with:
22-
python-version: '3.9'
21+
python-version: '3.13'
2322
- name: Setup uv
2423
uses: astral-sh/setup-uv@v7
2524
with:
26-
version: "0.4.15"
27-
enable-cache: true
2825
cache-dependency-glob: |
2926
requirements**.txt
3027
pyproject.toml
@@ -48,7 +45,7 @@ jobs:
4845
done
4946
env:
5047
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
51-
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 95
48+
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 99
5249
SMOKESHOW_GITHUB_CONTEXT: coverage
5350
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5451
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,14 @@ jobs:
124124
run: uv pip install -r requirements-tests.txt
125125
- run: ls -la coverage
126126
- run: coverage combine coverage
127-
- run: coverage report
128127
- run: coverage html --title "Coverage for ${{ github.sha }}"
129128
- name: Store coverage HTML
130129
uses: actions/upload-artifact@v5
131130
with:
132131
name: coverage-html
133132
path: htmlcov
134133
include-hidden-files: true
134+
- run: coverage report --fail-under=99
135135

136136
# https://github.com/marketplace/actions/alls-green#why
137137
alls-green: # This job does nothing and is only used for the branch protection

docs/release-notes.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
## Latest Changes
44

5+
## 0.0.29
6+
7+
### Fixes
8+
9+
* 🐛 Fix `alias` support for Pydantic v2. PR [#1577](https://github.com/fastapi/sqlmodel/pull/1577) by [@ravishan16](https://github.com/ravishan16).
10+
11+
## 0.0.28
12+
13+
### Fixes
14+
15+
* 🐛 Fix `RuntimeError: dictionary changed size during iteration` in `sqlmodel_update()`. PR [#997](https://github.com/fastapi/sqlmodel/pull/997) by [@BartSchuurmans](https://github.com/BartSchuurmans).
16+
517
### Docs
618

719
* 💅 Update CSS to explicitly use emoji font. PR [#1658](https://github.com/fastapi/sqlmodel/pull/1658) by [@tiangolo](https://github.com/tiangolo).
@@ -10,6 +22,9 @@
1022

1123
### Internal
1224

25+
* 📌 Pin FastAPI in tests to 0.125.0 while dropping support for Python 3.8. PR [#1689](https://github.com/fastapi/sqlmodel/pull/1689) by [@tiangolo](https://github.com/tiangolo).
26+
* 👷 Configure coverage, error on main tests, don't wait for Smokeshow. PR [#1683](https://github.com/fastapi/sqlmodel/pull/1683) by [@YuriiMotov](https://github.com/YuriiMotov).
27+
* 👷 Run Smokeshow always, even on test failures. PR [#1682](https://github.com/fastapi/sqlmodel/pull/1682) by [@YuriiMotov](https://github.com/YuriiMotov).
1328
* ⬆ Bump ruff from 0.14.6 to 0.14.8. PR [#1667](https://github.com/fastapi/sqlmodel/pull/1667) by [@dependabot[bot]](https://github.com/apps/dependabot).
1429
*[pre-commit.ci] pre-commit autoupdate. PR [#1662](https://github.com/fastapi/sqlmodel/pull/1662) by [@pre-commit-ci[bot]](https://github.com/apps/pre-commit-ci).
1530
* ⬆ Bump actions/checkout from 5 to 6. PR [#1656](https://github.com/fastapi/sqlmodel/pull/1656) by [@dependabot[bot]](https://github.com/apps/dependabot).

requirements-tests.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mypy ==1.14.1; python_version < "3.9"
77
mypy ==1.18.2; python_version >= "3.9"
88
ruff ==0.14.8
99
# For FastAPI tests
10-
fastapi >=0.103.2
10+
fastapi >=0.103.2,<0.126.0
1111
httpx ==0.28.1
1212
dirty-equals ==0.9.0
1313
jinja2 ==3.1.6

sqlmodel/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.0.27"
1+
__version__ = "0.0.29"
22

33
# Re-export from SQLAlchemy
44
from sqlalchemy.engine import create_engine as create_engine

sqlmodel/main.py

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ def Field(
219219
*,
220220
default_factory: Optional[NoArgAnyCallable] = None,
221221
alias: Optional[str] = None,
222+
validation_alias: Optional[str] = None,
223+
serialization_alias: Optional[str] = None,
222224
title: Optional[str] = None,
223225
description: Optional[str] = None,
224226
exclude: Union[
@@ -264,6 +266,8 @@ def Field(
264266
*,
265267
default_factory: Optional[NoArgAnyCallable] = None,
266268
alias: Optional[str] = None,
269+
validation_alias: Optional[str] = None,
270+
serialization_alias: Optional[str] = None,
267271
title: Optional[str] = None,
268272
description: Optional[str] = None,
269273
exclude: Union[
@@ -318,6 +322,8 @@ def Field(
318322
*,
319323
default_factory: Optional[NoArgAnyCallable] = None,
320324
alias: Optional[str] = None,
325+
validation_alias: Optional[str] = None,
326+
serialization_alias: Optional[str] = None,
321327
title: Optional[str] = None,
322328
description: Optional[str] = None,
323329
exclude: Union[
@@ -385,6 +391,8 @@ def Field(
385391
*,
386392
default_factory: Optional[NoArgAnyCallable] = None,
387393
alias: Optional[str] = None,
394+
validation_alias: Optional[str] = None,
395+
serialization_alias: Optional[str] = None,
388396
title: Optional[str] = None,
389397
description: Optional[str] = None,
390398
exclude: Union[
@@ -423,42 +431,61 @@ def Field(
423431
schema_extra: Optional[Dict[str, Any]] = None,
424432
) -> Any:
425433
current_schema_extra = schema_extra or {}
434+
# Extract possible alias settings from schema_extra so we can control precedence
435+
schema_validation_alias = current_schema_extra.pop("validation_alias", None)
436+
schema_serialization_alias = current_schema_extra.pop("serialization_alias", None)
437+
field_info_kwargs = {
438+
"alias": alias,
439+
"title": title,
440+
"description": description,
441+
"exclude": exclude,
442+
"include": include,
443+
"const": const,
444+
"gt": gt,
445+
"ge": ge,
446+
"lt": lt,
447+
"le": le,
448+
"multiple_of": multiple_of,
449+
"max_digits": max_digits,
450+
"decimal_places": decimal_places,
451+
"min_items": min_items,
452+
"max_items": max_items,
453+
"unique_items": unique_items,
454+
"min_length": min_length,
455+
"max_length": max_length,
456+
"allow_mutation": allow_mutation,
457+
"regex": regex,
458+
"discriminator": discriminator,
459+
"repr": repr,
460+
"primary_key": primary_key,
461+
"foreign_key": foreign_key,
462+
"ondelete": ondelete,
463+
"unique": unique,
464+
"nullable": nullable,
465+
"index": index,
466+
"sa_type": sa_type,
467+
"sa_column": sa_column,
468+
"sa_column_args": sa_column_args,
469+
"sa_column_kwargs": sa_column_kwargs,
470+
**current_schema_extra,
471+
}
472+
if IS_PYDANTIC_V2:
473+
# explicit params > schema_extra > alias propagation
474+
field_info_kwargs["validation_alias"] = (
475+
validation_alias or schema_validation_alias or alias
476+
)
477+
field_info_kwargs["serialization_alias"] = (
478+
serialization_alias or schema_serialization_alias or alias
479+
)
480+
else:
481+
if validation_alias or schema_validation_alias is not None:
482+
raise RuntimeError("validation_alias is not supported in Pydantic v1")
483+
if serialization_alias or schema_serialization_alias is not None:
484+
raise RuntimeError("serialization_alias is not supported in Pydantic v1")
426485
field_info = FieldInfo(
427486
default,
428487
default_factory=default_factory,
429-
alias=alias,
430-
title=title,
431-
description=description,
432-
exclude=exclude,
433-
include=include,
434-
const=const,
435-
gt=gt,
436-
ge=ge,
437-
lt=lt,
438-
le=le,
439-
multiple_of=multiple_of,
440-
max_digits=max_digits,
441-
decimal_places=decimal_places,
442-
min_items=min_items,
443-
max_items=max_items,
444-
unique_items=unique_items,
445-
min_length=min_length,
446-
max_length=max_length,
447-
allow_mutation=allow_mutation,
448-
regex=regex,
449-
discriminator=discriminator,
450-
repr=repr,
451-
primary_key=primary_key,
452-
foreign_key=foreign_key,
453-
ondelete=ondelete,
454-
unique=unique,
455-
nullable=nullable,
456-
index=index,
457-
sa_type=sa_type,
458-
sa_column=sa_column,
459-
sa_column_args=sa_column_args,
460-
sa_column_kwargs=sa_column_kwargs,
461-
**current_schema_extra,
488+
**field_info_kwargs,
462489
)
463490
field_metadata = FieldInfoMetadata(
464491
primary_key=primary_key,
@@ -1053,9 +1080,8 @@ def sqlmodel_update(
10531080
else:
10541081
value = getattr(obj, key)
10551082
setattr(self, key, value)
1056-
for remaining_key in use_update:
1083+
for remaining_key, value in use_update.items():
10571084
if remaining_key in get_model_fields(self):
1058-
value = use_update.pop(remaining_key)
10591085
setattr(self, remaining_key, value)
10601086
else:
10611087
raise ValueError(

0 commit comments

Comments
 (0)