Skip to content

Commit d6472fa

Browse files
committed
Tortoise.init() refactoring and transactions module
1 parent 6031467 commit d6472fa

31 files changed

Lines changed: 903 additions & 375 deletions

CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changelog
22
=========
33

4+
0.10.0
5+
------
6+
- Refactored ``Tortoise.init()`` to init all connections and discover models from config passed
7+
as argument
8+
- New ``transactions`` module for implicit working with transactions
9+
410
0.9.4
511
-----
612
- No more asserts, only Tortoise Exceptions

examples/aggregation.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
from tortoise import Tortoise, fields
44
from tortoise.aggregation import Count, Min, Sum
5-
from tortoise.backends.sqlite.client import SqliteClient
65
from tortoise.models import Model
7-
from tortoise.utils import generate_schema
86

97

108
class Tournament(Model):
@@ -38,12 +36,9 @@ def __str__(self):
3836

3937

4038
async def run():
41-
client = SqliteClient('example_aggregation.sqlite3')
42-
await client.create_connection()
43-
Tortoise.init(client)
44-
await generate_schema(client)
45-
46-
tournament = Tournament(name='New Tournament')
39+
await Tortoise.init(config_file='config.json')
40+
await Tortoise.generate_schemas()
41+
tournament = await Tournament.create(name='New Tournament')
4742
await tournament.save()
4843
await Tournament.create(name='Second tournament')
4944
await Event(name='Without participants', tournament_id=tournament.id).save()

examples/basic.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
import asyncio
55

66
from tortoise import Tortoise, fields
7-
from tortoise.backends.sqlite.client import SqliteClient
87
from tortoise.models import Model
9-
from tortoise.utils import generate_schema
108

119

1210
class Event(Model):
@@ -22,11 +20,8 @@ def __str__(self):
2220

2321

2422
async def run():
25-
client = SqliteClient('example_basic.sqlite3')
26-
await client.create_connection()
27-
Tortoise.init(client)
28-
29-
await generate_schema(client)
23+
await Tortoise.init(config_file='config.json')
24+
await Tortoise.generate_schemas()
3025

3126
event = await Event.create(name='Test')
3227
await Event.filter(id=event.id).update(name='Updated name')

examples/complex_filtering.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
import asyncio
77

88
from tortoise import Tortoise, fields
9-
from tortoise.backends.sqlite.client import SqliteClient
109
from tortoise.models import Model
1110
from tortoise.query_utils import Q
12-
from tortoise.utils import generate_schema
1311

1412

1513
class Tournament(Model):
@@ -41,10 +39,8 @@ def __str__(self):
4139

4240

4341
async def run():
44-
client = SqliteClient('example_filtering.sqlite3')
45-
await client.create_connection()
46-
Tortoise.init(client)
47-
await generate_schema(client)
42+
await Tortoise.init(config_file='config.json')
43+
await Tortoise.generate_schemas()
4844

4945
tournament = Tournament(name='Tournament')
5046
await tournament.save()

examples/complex_prefetching.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import asyncio
22

33
from tortoise import Tortoise, fields
4-
from tortoise.backends.sqlite.client import SqliteClient
54
from tortoise.models import Model
65
from tortoise.query_utils import Prefetch
7-
from tortoise.utils import generate_schema
86

97

108
class Tournament(Model):
@@ -36,10 +34,8 @@ def __str__(self):
3634

3735

3836
async def run():
39-
client = SqliteClient('example_prefetching.sqlite3')
40-
await client.create_connection()
41-
Tortoise.init(client)
42-
await generate_schema(client)
37+
await Tortoise.init(config_file='config.json')
38+
await Tortoise.generate_schemas()
4339

4440
tournament = await Tournament.create(name='tournament')
4541
await Event.create(name='First', tournament=tournament)

examples/config.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"connections": {
3+
"default": {
4+
"engine": "tortoise.backends.sqlite",
5+
"credentials": {
6+
"file_path": "example.sqlite3"
7+
}
8+
}
9+
},
10+
"apps": {
11+
"models": {
12+
"models": [
13+
"__main__"
14+
],
15+
"default_connection": "default"
16+
}
17+
}
18+
}

examples/postgres.py

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@
22
This example showcases special postgres features
33
"""
44
import asyncio
5-
from copy import copy
6-
7-
from asyncpg import InvalidCatalogNameError
85

96
from tortoise import Tortoise, fields
10-
from tortoise.backends.asyncpg.client import AsyncpgDBClient
117
from tortoise.models import Model
12-
from tortoise.utils import generate_schema
138

149

1510
class Report(Model):
@@ -20,41 +15,35 @@ def __str__(self):
2015
return str(self.id)
2116

2217

23-
CONNECTION_PARAMS = {
24-
'host': 'localhost',
25-
'port': '54325',
26-
'user': 'tortoise',
27-
'password': 'qwerty123',
28-
'database': 'tortoise',
29-
}
30-
31-
3218
async def run():
33-
client = AsyncpgDBClient(single_connection=True, **CONNECTION_PARAMS)
34-
test_db_name = CONNECTION_PARAMS['database'] + '_test'
35-
await client.create_connection()
36-
37-
try:
38-
await client.execute_script('DROP DATABASE {}'.format(test_db_name))
39-
except InvalidCatalogNameError:
40-
pass
41-
await client.execute_script(
42-
'CREATE DATABASE {} OWNER {}'.format(test_db_name, CONNECTION_PARAMS["user"])
43-
)
44-
await client.close()
45-
test_db_connection_params = copy(CONNECTION_PARAMS)
46-
test_db_connection_params['database'] = test_db_name
47-
48-
client = AsyncpgDBClient(single_connection=True, **test_db_connection_params)
49-
await client.create_connection()
50-
Tortoise.init(client)
51-
await generate_schema(client)
19+
await Tortoise.init({
20+
'connections': {
21+
'default': {
22+
'engine': 'tortoise.backends.asyncpg',
23+
'credentials': {
24+
'host': 'localhost',
25+
'port': '54325',
26+
'user': 'tortoise',
27+
'password': 'qwerty123',
28+
'database': 'test',
29+
}
30+
}
31+
},
32+
'apps': {
33+
'models': {
34+
'models': ['__main__'],
35+
'default_connection': 'default',
36+
}
37+
}
38+
}, _create_db=True)
39+
await Tortoise.generate_schemas()
5240

5341
report_data = {
5442
'foo': 'bar',
5543
}
5644
print(await Report.create(content=report_data))
5745
print(await Report.filter(content=report_data).first())
46+
await Tortoise._drop_databases()
5847

5948

6049
if __name__ == '__main__':

examples/relations.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@
88
import asyncio
99

1010
from tortoise import Tortoise, fields
11-
from tortoise.backends.sqlite.client import SqliteClient
1211
from tortoise.exceptions import NoValuesFetched
1312
from tortoise.models import Model
14-
from tortoise.utils import generate_schema
1513

1614

1715
class Tournament(Model):
@@ -43,10 +41,8 @@ def __str__(self):
4341

4442

4543
async def run():
46-
client = SqliteClient('example_relations.sqlite3')
47-
await client.create_connection()
48-
Tortoise.init(client)
49-
await generate_schema(client)
44+
await Tortoise.init(config_file='config.json')
45+
await Tortoise.generate_schemas()
5046

5147
tournament = Tournament(name='New Tournament')
5248
await tournament.save()

examples/schema_create.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import os
44

55
from tortoise import Tortoise, fields
6-
from tortoise.backends.sqlite.client import SqliteClient
76
from tortoise.models import Model
8-
from tortoise.utils import generate_schema
97

108

119
class Tournament(Model):
@@ -45,10 +43,8 @@ def __str__(self):
4543

4644

4745
async def run():
48-
client = SqliteClient('example_schema.sqlite3')
49-
await client.create_connection()
50-
Tortoise.init(client)
51-
await generate_schema(client)
46+
await Tortoise.init(config_file='config.json')
47+
await Tortoise.generate_schemas()
5248

5349
tournament = await Tournament.create(name='Test')
5450

examples/transactions.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
"""
22
This example demonstrates how you can use transactions with tortoise
3-
4-
Currently tortoise doesn't have some kind of magic transaction wrapper
5-
like django's transaction.atomic, but if you have to make something in transaction
6-
you could still do it like this
73
"""
84
import asyncio
9-
import sqlite3
105

116
from tortoise import Tortoise, fields
12-
from tortoise.backends.sqlite.client import SqliteClient
7+
from tortoise.transactions import in_transaction, atomic
8+
from tortoise.exceptions import OperationalError
139
from tortoise.models import Model
14-
from tortoise.utils import generate_schema
1510

1611

1712
class Event(Model):
@@ -26,19 +21,32 @@ def __str__(self):
2621

2722

2823
async def run():
29-
client = SqliteClient('example_transaction.sqlite3')
30-
await client.create_connection()
31-
Tortoise.init(client)
32-
await generate_schema(client)
24+
await Tortoise.init(config_file='config.json')
25+
await Tortoise.generate_schemas()
3326

3427
try:
35-
async with client.in_transaction() as connection:
28+
async with in_transaction() as connection:
3629
event = Event(name='Test')
3730
await event.save(using_db=connection)
3831
await Event.filter(id=event.id).using_db(connection).update(name='Updated name')
3932
saved_event = await Event.filter(name='Updated name').using_db(connection).first()
4033
await connection.execute_query('SELECT * FROM non_existent_table')
41-
except sqlite3.OperationalError:
34+
except OperationalError:
35+
pass
36+
saved_event = await Event.filter(name='Updated name').first()
37+
print(saved_event)
38+
39+
@atomic()
40+
async def bound_to_fall():
41+
event = await Event.create(name='Test')
42+
await Event.filter(id=event.id).update(name='Updated name')
43+
saved_event = await Event.filter(name='Updated name').first()
44+
print(saved_event.name)
45+
raise OperationalError()
46+
47+
try:
48+
await bound_to_fall()
49+
except OperationalError:
4250
pass
4351
saved_event = await Event.filter(name='Updated name').first()
4452
print(saved_event)

0 commit comments

Comments
 (0)