Skip to content

Commit fb60073

Browse files
authored
Merge branch 'main' into async
2 parents af84d75 + e05eae6 commit fb60073

28 files changed

+663
-214
lines changed

.github/workflows/build-docs.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,17 @@ jobs:
6363
if: steps.cache.outputs.cache-hit != 'true'
6464
run: python -m poetry install
6565
- name: Install Material for MkDocs Insiders
66-
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
66+
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' ) && steps.cache.outputs.cache-hit != 'true'
6767
run: python -m poetry run pip install git+https://${{ secrets.SQLMODEL_MKDOCS_MATERIAL_INSIDERS }}@github.com/squidfunk/mkdocs-material-insiders.git
6868
- uses: actions/cache@v3
6969
with:
7070
key: mkdocs-cards-${{ github.ref }}
7171
path: .cache
7272
- name: Build Docs
73-
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true
73+
if: github.event_name == 'pull_request' && github.secret_source != 'Actions'
7474
run: python -m poetry run mkdocs build
7575
- name: Build Docs with Insiders
76-
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
76+
if: github.event_name != 'pull_request' || github.secret_source == 'Actions'
7777
run: python -m poetry run mkdocs build --config-file mkdocs.insiders.yml
7878
- uses: actions/upload-artifact@v3
7979
with:

.github/workflows/latest-changes.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ jobs:
3030
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
3131
with:
3232
limit-access-to-actor: true
33-
- uses: docker://tiangolo/latest-changes:0.0.3
33+
- uses: docker://tiangolo/latest-changes:0.2.0
34+
# - uses: tiangolo/latest-changes@main
3435
with:
3536
token: ${{ secrets.GITHUB_TOKEN }}
3637
latest_changes_file: docs/release-notes.md
37-
latest_changes_header: '## Latest Changes\n\n'
38+
latest_changes_header: '## Latest Changes'
39+
end_regex: '^## '
3840
debug_logs: true
41+
label_header_prefix: '### '

.pre-commit-config.yaml

+3-13
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,13 @@ repos:
1313
- --unsafe
1414
- id: end-of-file-fixer
1515
- id: trailing-whitespace
16-
- repo: https://github.com/asottile/pyupgrade
17-
rev: v3.15.0
18-
hooks:
19-
- id: pyupgrade
20-
args:
21-
- --py3-plus
22-
- --keep-runtime-typing
23-
- repo: https://github.com/astral-sh/ruff-pre-commit
24-
rev: v0.1.1
16+
- repo: https://github.com/charliermarsh/ruff-pre-commit
17+
rev: v0.1.2
2518
hooks:
2619
- id: ruff
2720
args:
2821
- --fix
29-
- repo: https://github.com/psf/black
30-
rev: 23.10.0
31-
hooks:
32-
- id: black
22+
- id: ruff-format
3323
ci:
3424
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
3525
autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate

docs/release-notes.md

+34
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,40 @@
22

33
## Latest Changes
44

5+
### Internal
6+
7+
* 👷 Upgrade latest-changes GitHub Action. PR [#693](https://github.com/tiangolo/sqlmodel/pull/693) by [@tiangolo](https://github.com/tiangolo).
8+
9+
## 0.0.11
10+
11+
### Features
12+
13+
* ✨ Add support for passing a custom SQLAlchemy type to `Field()` with `sa_type`. PR [#505](https://github.com/tiangolo/sqlmodel/pull/505) by [@maru0123-2004](https://github.com/maru0123-2004).
14+
* You might consider this a breaking change if you were using an incompatible combination of arguments, those arguments were not taking effect and now you will have a type error and runtime error telling you that.
15+
* ✨ Do not allow invalid combinations of field parameters for columns and relationships, `sa_column` excludes `sa_column_args`, `primary_key`, `nullable`, etc. PR [#681](https://github.com/tiangolo/sqlmodel/pull/681) by [@tiangolo](https://github.com/tiangolo).
16+
17+
### Docs
18+
19+
* 🎨 Update inline source examples, hide `#` in annotations (from MkDocs Material). PR [#677](https://github.com/tiangolo/sqlmodel/pull/677) by [@Matthieu-LAURENT39](https://github.com/Matthieu-LAURENT39).
20+
21+
### Internal
22+
23+
* ⬆ Update coverage requirement from ^6.2 to >=6.2,<8.0. PR [#663](https://github.com/tiangolo/sqlmodel/pull/663) by [@dependabot[bot]](https://github.com/apps/dependabot).
24+
* ⬆ Update mkdocs-material requirement from 9.1.21 to 9.2.7. PR [#675](https://github.com/tiangolo/sqlmodel/pull/675) by [@dependabot[bot]](https://github.com/apps/dependabot).
25+
* ⬆️ Upgrade mypy manually. PR [#684](https://github.com/tiangolo/sqlmodel/pull/684) by [@tiangolo](https://github.com/tiangolo).
26+
* ⬆ Update black requirement from ^22.10.0 to >=22.10,<24.0. PR [#664](https://github.com/tiangolo/sqlmodel/pull/664) by [@dependabot[bot]](https://github.com/apps/dependabot).
27+
* 👷 Update CI to build MkDocs Insiders only when the secrets are available, for Dependabot. PR [#683](https://github.com/tiangolo/sqlmodel/pull/683) by [@tiangolo](https://github.com/tiangolo).
28+
29+
## 0.0.10
30+
31+
### Features
32+
33+
* ✨ Add support for all `Field` parameters from Pydantic `1.9.0` and above, make Pydantic `1.9.0` the minimum required version. PR [#440](https://github.com/tiangolo/sqlmodel/pull/440) by [@daniil-berg](https://github.com/daniil-berg).
34+
35+
### Internal
36+
37+
* 🔧 Adopt Ruff for formatting. PR [#679](https://github.com/tiangolo/sqlmodel/pull/679) by [@tiangolo](https://github.com/tiangolo).
38+
539
## 0.0.9
640

741
### Breaking Changes

docs_src/tutorial/automatic_id_none_refresh/tutorial002.py

+50-50
Original file line numberDiff line numberDiff line change
@@ -21,56 +21,56 @@ def create_db_and_tables():
2121

2222

2323
def create_heroes():
24-
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson") # (1)
25-
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador") # (2)
26-
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48) # (3)
27-
28-
print("Before interacting with the database") # (4)
29-
print("Hero 1:", hero_1) # (5)
30-
print("Hero 2:", hero_2) # (6)
31-
print("Hero 3:", hero_3) # (7)
32-
33-
with Session(engine) as session: # (8)
34-
session.add(hero_1) # (9)
35-
session.add(hero_2) # (10)
36-
session.add(hero_3) # (11)
37-
38-
print("After adding to the session") # (12)
39-
print("Hero 1:", hero_1) # (13)
40-
print("Hero 2:", hero_2) # (14)
41-
print("Hero 3:", hero_3) # (15)
42-
43-
session.commit() # (16)
44-
45-
print("After committing the session") # (17)
46-
print("Hero 1:", hero_1) # (18)
47-
print("Hero 2:", hero_2) # (19)
48-
print("Hero 3:", hero_3) # (20)
49-
50-
print("After committing the session, show IDs") # (21)
51-
print("Hero 1 ID:", hero_1.id) # (22)
52-
print("Hero 2 ID:", hero_2.id) # (23)
53-
print("Hero 3 ID:", hero_3.id) # (24)
54-
55-
print("After committing the session, show names") # (25)
56-
print("Hero 1 name:", hero_1.name) # (26)
57-
print("Hero 2 name:", hero_2.name) # (27)
58-
print("Hero 3 name:", hero_3.name) # (28)
59-
60-
session.refresh(hero_1) # (29)
61-
session.refresh(hero_2) # (30)
62-
session.refresh(hero_3) # (31)
63-
64-
print("After refreshing the heroes") # (32)
65-
print("Hero 1:", hero_1) # (33)
66-
print("Hero 2:", hero_2) # (34)
67-
print("Hero 3:", hero_3) # (35)
68-
# (36)
69-
70-
print("After the session closes") # (37)
71-
print("Hero 1:", hero_1) # (38)
72-
print("Hero 2:", hero_2) # (39)
73-
print("Hero 3:", hero_3) # (40)
24+
hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson") # (1)!
25+
hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador") # (2)!
26+
hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48) # (3)!
27+
28+
print("Before interacting with the database") # (4)!
29+
print("Hero 1:", hero_1) # (5)!
30+
print("Hero 2:", hero_2) # (6)!
31+
print("Hero 3:", hero_3) # (7)!
32+
33+
with Session(engine) as session: # (8)!
34+
session.add(hero_1) # (9)!
35+
session.add(hero_2) # (10)!
36+
session.add(hero_3) # (11)!
37+
38+
print("After adding to the session") # (12)!
39+
print("Hero 1:", hero_1) # (13)!
40+
print("Hero 2:", hero_2) # (14)!
41+
print("Hero 3:", hero_3) # (15)!
42+
43+
session.commit() # (16)!
44+
45+
print("After committing the session") # (17)!
46+
print("Hero 1:", hero_1) # (18)!
47+
print("Hero 2:", hero_2) # (19)!
48+
print("Hero 3:", hero_3) # (20)!
49+
50+
print("After committing the session, show IDs") # (21)!
51+
print("Hero 1 ID:", hero_1.id) # (22)!
52+
print("Hero 2 ID:", hero_2.id) # (23)!
53+
print("Hero 3 ID:", hero_3.id) # (24)!
54+
55+
print("After committing the session, show names") # (25)!
56+
print("Hero 1 name:", hero_1.name) # (26)!
57+
print("Hero 2 name:", hero_2.name) # (27)!
58+
print("Hero 3 name:", hero_3.name) # (28)!
59+
60+
session.refresh(hero_1) # (29)!
61+
session.refresh(hero_2) # (30)!
62+
session.refresh(hero_3) # (31)!
63+
64+
print("After refreshing the heroes") # (32)!
65+
print("Hero 1:", hero_1) # (33)!
66+
print("Hero 2:", hero_2) # (34)!
67+
print("Hero 3:", hero_3) # (35)!
68+
# (36)!
69+
70+
print("After the session closes") # (37)!
71+
print("Hero 1:", hero_1) # (38)!
72+
print("Hero 2:", hero_2) # (39)!
73+
print("Hero 3:", hero_3) # (40)!
7474

7575

7676
def main():
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
from typing import Optional # (1)
1+
from typing import Optional # (1)!
22

3-
from sqlmodel import Field, SQLModel, create_engine # (2)
3+
from sqlmodel import Field, SQLModel, create_engine # (2)!
44

55

6-
class Hero(SQLModel, table=True): # (3)
7-
id: Optional[int] = Field(default=None, primary_key=True) # (4)
8-
name: str # (5)
9-
secret_name: str # (6)
10-
age: Optional[int] = None # (7)
6+
class Hero(SQLModel, table=True): # (3)!
7+
id: Optional[int] = Field(default=None, primary_key=True) # (4)!
8+
name: str # (5)!
9+
secret_name: str # (6)!
10+
age: Optional[int] = None # (7)!
1111

1212

13-
sqlite_file_name = "database.db" # (8)
14-
sqlite_url = f"sqlite:///{sqlite_file_name}" # (9)
13+
sqlite_file_name = "database.db" # (8)!
14+
sqlite_url = f"sqlite:///{sqlite_file_name}" # (9)!
1515

16-
engine = create_engine(sqlite_url, echo=True) # (10)
16+
engine = create_engine(sqlite_url, echo=True) # (10)!
1717

1818

19-
def create_db_and_tables(): # (11)
20-
SQLModel.metadata.create_all(engine) # (12)
19+
def create_db_and_tables(): # (11)!
20+
SQLModel.metadata.create_all(engine) # (12)!
2121

2222

23-
if __name__ == "__main__": # (13)
24-
create_db_and_tables() # (14)
23+
if __name__ == "__main__": # (13)!
24+
create_db_and_tables() # (14)!

docs_src/tutorial/delete/tutorial002.py

+13-13
Original file line numberDiff line numberDiff line change
@@ -71,23 +71,23 @@ def update_heroes():
7171

7272
def delete_heroes():
7373
with Session(engine) as session:
74-
statement = select(Hero).where(Hero.name == "Spider-Youngster") # (1)
75-
results = session.exec(statement) # (2)
76-
hero = results.one() # (3)
77-
print("Hero: ", hero) # (4)
74+
statement = select(Hero).where(Hero.name == "Spider-Youngster") # (1)!
75+
results = session.exec(statement) # (2)!
76+
hero = results.one() # (3)!
77+
print("Hero: ", hero) # (4)!
7878

79-
session.delete(hero) # (5)
80-
session.commit() # (6)
79+
session.delete(hero) # (5)!
80+
session.commit() # (6)!
8181

82-
print("Deleted hero:", hero) # (7)
82+
print("Deleted hero:", hero) # (7)!
8383

84-
statement = select(Hero).where(Hero.name == "Spider-Youngster") # (8)
85-
results = session.exec(statement) # (9)
86-
hero = results.first() # (10)
84+
statement = select(Hero).where(Hero.name == "Spider-Youngster") # (8)!
85+
results = session.exec(statement) # (9)!
86+
hero = results.first() # (10)!
8787

88-
if hero is None: # (11)
89-
print("There's no hero named Spider-Youngster") # (12)
90-
# (13)
88+
if hero is None: # (11)!
89+
print("There's no hero named Spider-Youngster") # (12)!
90+
# (13)!
9191

9292

9393
def main():
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastapi.testclient import TestClient
22
from sqlmodel import Session, SQLModel, create_engine
33

4-
from .main import app, get_session # (1)
4+
from .main import app, get_session # (1)!
55

66

77
def test_create_hero():
@@ -17,16 +17,16 @@ def get_session_override():
1717

1818
app.dependency_overrides[get_session] = get_session_override
1919

20-
client = TestClient(app) # (2)
20+
client = TestClient(app) # (2)!
2121

22-
response = client.post( # (3)
22+
response = client.post( # (3)!
2323
"/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
2424
)
2525
app.dependency_overrides.clear()
26-
data = response.json() # (4)
26+
data = response.json() # (4)!
2727

28-
assert response.status_code == 200 # (5)
29-
assert data["name"] == "Deadpond" # (6)
30-
assert data["secret_name"] == "Dive Wilson" # (7)
31-
assert data["age"] is None # (8)
32-
assert data["id"] is not None # (9)
28+
assert response.status_code == 200 # (5)!
29+
assert data["name"] == "Deadpond" # (6)!
30+
assert data["secret_name"] == "Dive Wilson" # (7)!
31+
assert data["age"] is None # (8)!
32+
assert data["id"] is not None # (9)!

docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_002.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from fastapi.testclient import TestClient
22
from sqlmodel import Session, SQLModel, create_engine
33

4-
from .main import app, get_session # (1)
4+
from .main import app, get_session # (1)!
55

66

77
def test_create_hero():
@@ -12,17 +12,17 @@ def test_create_hero():
1212

1313
with Session(engine) as session:
1414

15-
def get_session_override(): # (2)
16-
return session # (3)
15+
def get_session_override(): # (2)!
16+
return session # (3)!
1717

18-
app.dependency_overrides[get_session] = get_session_override # (4)
18+
app.dependency_overrides[get_session] = get_session_override # (4)!
1919

2020
client = TestClient(app)
2121

2222
response = client.post(
2323
"/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
2424
)
25-
app.dependency_overrides.clear() # (5)
25+
app.dependency_overrides.clear() # (5)!
2626
data = response.json()
2727

2828
assert response.status_code == 200
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
from fastapi.testclient import TestClient
22
from sqlmodel import Session, SQLModel, create_engine
33

4-
from .main import app, get_session # (1)
4+
from .main import app, get_session # (1)!
55

66

77
def test_create_hero():
8-
engine = create_engine( # (2)
8+
engine = create_engine( # (2)!
99
"sqlite:///testing.db", connect_args={"check_same_thread": False}
1010
)
11-
SQLModel.metadata.create_all(engine) # (3)
11+
SQLModel.metadata.create_all(engine) # (3)!
1212

13-
with Session(engine) as session: # (4)
13+
with Session(engine) as session: # (4)!
1414

1515
def get_session_override():
16-
return session # (5)
16+
return session # (5)!
1717

18-
app.dependency_overrides[get_session] = get_session_override # (4)
18+
app.dependency_overrides[get_session] = get_session_override # (4)!
1919

2020
client = TestClient(app)
2121

@@ -30,4 +30,4 @@ def get_session_override():
3030
assert data["secret_name"] == "Dive Wilson"
3131
assert data["age"] is None
3232
assert data["id"] is not None
33-
# (6)
33+
# (6)!

0 commit comments

Comments
 (0)