async def run(): client = AsyncpgDBClient(single_connection=True, **CONNECTION_PARAMS) test_db_name = CONNECTION_PARAMS['database'] + '_test' await client.create_connection() try: await client.execute_script('DROP DATABASE {}'.format(test_db_name)) except InvalidCatalogNameError: pass await client.execute_script( 'CREATE DATABASE {} OWNER {}'.format(test_db_name, CONNECTION_PARAMS["user"]) ) await client.close() test_db_connection_params = copy(CONNECTION_PARAMS) test_db_connection_params['database'] = test_db_name client = AsyncpgDBClient(single_connection=True, **test_db_connection_params) await client.create_connection() Tortoise.init(client) await generate_schema(client) report_data = { 'foo': 'bar', } print(await Report.create(content=report_data)) print(await Report.filter(content=report_data).first())
async def run(): Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.open_connections() await Tortoise.generate_schemas() root = await Employee.create(name="Root") loose = await Employee.create(name="Loose") _1 = await Employee.create(name="1. First H1", manager=root) _2 = await Employee.create(name="2. Second H1", manager=root) _1_1 = await Employee.create(name="1.1. First H2", manager=_1) _1_1_1 = await Employee.create(name="1.1.1. First H3", manager=_1_1) _2_1 = await Employee.create(name="2.1. Second H2", manager=_2) _2_2 = await Employee.create(name="2.2. Third H2", manager=_2) await _1.talks_to.add(_2, _1_1_1, loose) await _2_1.gets_talked_to.add(_2_2, _1_1, loose) # Evaluated off creation objects print(await loose.full_hierarchy__fetch_related()) print(await root.full_hierarchy__async_for()) print(await root.full_hierarchy__fetch_related()) # Evaluated off new objects → Result is identical root2 = await Employee.get(name="Root") loose2 = await Employee.get(name="Loose") print(await loose2.full_hierarchy__fetch_related()) print(await root2.full_hierarchy__async_for()) print(await root2.full_hierarchy__fetch_related())
async def run(): Tortoise.init( { "connections": { "default": { "engine": "tortoise.backends.asyncpg", "host": "localhost", "port": "5432", "user": "******", "password": "******", "database": "test", } }, "apps": { "models": { "models": ["__main__"], "default_connection": "default" } }, }, ) await Tortoise.open_connections(create_db=True) await Tortoise.generate_schemas() report_data = {"foo": "bar"} print(await Report.create(content=report_data)) print(await Report.filter(content=report_data).first()) await Tortoise.drop_databases()
def tortoise_implementation(): [ os.remove(f"./db.sqlite3{s}") for s in ["", "-wal", "-shm"] if os.path.exists(f"./db.sqlite3{s}") ] app = FastAPI(on_shutdown=[on_shutdown]) Tortoise.init(config=TORTOISE_ORM) Tortoise.generate_schemas() router_settings = [ dict( schema=Potato, db_model=PotatoModel, prefix="potato", paginate=PAGINATION_SIZE, ), dict( schema=Carrot, db_model=CarrotModel, create_schema=CarrotCreate, update_schema=CarrotUpdate, prefix="carrot", tags=CUSTOM_TAGS, ), ] return app, TortoiseCRUDRouter, router_settings
async def test_schema(self): from asyncpg.exceptions import InvalidSchemaNameError self.db_config["connections"]["models"]["schema"] = "mytestschema" Tortoise.init(self.db_config) await Tortoise.open_connections(create_db=True) with self.assertRaises(InvalidSchemaNameError): await Tortoise.generate_schemas() conn = Tortoise.get_db_client("models") await conn.execute_script("CREATE SCHEMA mytestschema;") await Tortoise.generate_schemas() tournament = await Tournament.create(name="Test") await Tortoise.close_connections() del self.db_config["connections"]["models"]["schema"] Tortoise.init(self.db_config) await Tortoise.open_connections() with self.assertRaises(OperationalError): await Tournament.filter(name="Test").first() conn = Tortoise.get_db_client("models") _, db_columns, res = await conn.execute_query( "SELECT id, name FROM mytestschema.models_tournament WHERE name='Test' LIMIT 1" ) self.assertEqual(len(res), 1) self.assertEqual(tournament.id, res[0][0]) self.assertEqual(tournament.name, res[0][1])
async def run(): Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.open_connections() await Tortoise.generate_schemas() try: async with in_transaction() as connection: event = Event(name="Test") await event.save(using_db=connection) await Event.filter(id=event.id).using_db(connection).update( name="Updated name") saved_event = await Event.filter(name="Updated name" ).using_db(connection).first() await connection.execute_query("SELECT * FROM non_existent_table") except OperationalError: pass saved_event = await Event.filter(name="Updated name").first() print(saved_event) @atomic() async def bound_to_fall(): event = await Event.create(name="Test") await Event.filter(id=event.id).update(name="Updated name") saved_event = await Event.filter(name="Updated name").first() print(saved_event.name) raise OperationalError() try: await bound_to_fall() except OperationalError: pass saved_event = await Event.filter(name="Updated name").first() print(saved_event)
async def run(): client = SqliteClient('example_aggregation.sqlite3') await client.create_connection() Tortoise.init(client) await generate_schema(client) tournament = Tournament(name='New Tournament') await tournament.save() await Tournament.create(name='Second tournament') await Event(name='Without participants', tournament_id=tournament.id).save() event = Event(name='Test', tournament_id=tournament.id) await event.save() participants = [] for i in range(2): team = Team(name='Team {}'.format(i + 1)) await team.save() participants.append(team) await event.participants.add(participants[0], participants[1]) await event.participants.add(participants[0], participants[1]) print(await Tournament.all().annotate( events_count=Count('events'), ).filter(events_count__gte=1)) print(await Event.filter(id=event.id).first().annotate( lowest_team_id=Min('participants__id'))) print(await Tournament.all().annotate( events_count=Count('events'), ).order_by('events_count')) print(await Event.all().annotate( tournament_test_id=Sum('tournament__id'), ).first())
async def _setUpDB(self): self.db = await self.getDB() if not _Tortoise._inited: _Tortoise.init(self.db) else: _Tortoise._client_routing(self.db) await _generate_schema(self.db)
async def init_orm(app, loop): # pylint: disable=W0612 Tortoise.init(config=config, config_file=config_file, db_url=db_url, modules=modules) await Tortoise.open_connections() if generate_schemas: await Tortoise.generate_schemas()
async def inner() -> None: Tortoise.init(config=config, config_file=config_file, db_url=db_url, modules=modules) await Tortoise.open_connections() await Tortoise.generate_schemas() await Tortoise.close_connections()
async def test_ssl_true(self): self.db_config["connections"]["models"]["ssl"] = True try: Tortoise.init(self.db_config) await Tortoise.open_connections() except (ConnectionError, ssl.SSLError): pass else: self.assertFalse(True, "Expected ConnectionError or SSLError")
def test_init_no_apps(self): with self.assertRaisesRegex(ConfigurationError, 'Config must define "apps" section'): Tortoise.init({ "connections": { "default": { "engine": "tortoise.backends.sqlite", "file_path": ":memory:", } } })
def test_init_no_connections(self): with self.assertRaisesRegex( ConfigurationError, 'Config must define "connections" section'): Tortoise.init({ "apps": { "models": { "models": ["tests.testmodels"], "default_connection": "default" } } })
async def run(): Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.open_connections() await Tortoise.generate_schemas() tournament = await Tournament.create(name="tournament") await Event.create(name="First", tournament=tournament) await Event.create(name="Second", tournament=tournament) tournament_with_filtered = (await Tournament.all().prefetch_related( Prefetch("events", queryset=Event.filter(name="First"))).first()) print(tournament_with_filtered) print(await Tournament.first().prefetch_related("events"))
async def run(): client = SqliteClient('example_prefetching.sqlite3') await client.create_connection() Tortoise.init(client) await generate_schema(client) tournament = await Tournament.create(name='tournament') await Event.create(name='First', tournament=tournament) await Event.create(name='Second', tournament=tournament) tournament_with_filtered = await Tournament.all().prefetch_related( Prefetch('events', queryset=Event.filter(name='First'))).first() print(tournament_with_filtered) print(await Tournament.first().prefetch_related('events'))
async def test_ssl_custom(self): # Expect connectionerror or pass ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE self.db_config["connections"]["models"]["ssl"] = ctx try: Tortoise.init(self.db_config) await Tortoise.open_connections(create_db=True) except ConnectionError: pass
async def run(): Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.open_connections() await Tortoise.generate_schemas() event = await Event.create(name="Test") await Event.filter(id=event.id).update(name="Updated name") print(await Event.filter(name="Updated name").first()) await Event(name="Test 2").save() print(await Event.all().values_list("id", flat=True)) print(await Event.all().values("id", "name"))
def start_app(port): app = web.Application() logging.basicConfig( format='%(asctime)s %(name)s %(levelname)s %(message)s', level=settings.LOG_LEVEL ) app['db'] = DBAsyncClient(**DB_CONFIG) loop = asyncio.get_event_loop() loop.run_until_complete(app['db'].create_connection()) Tortoise.init(app['db']) loop.run_until_complete(run_migrations()) setup_routes(app) web.run_app(app, port=port)
def test_db_url_init(self): Tortoise.init({ "connections": { "default": f"sqlite://{':memory:'}" }, "apps": { "models": { "models": ["tests.testmodels"], "default_connection": "default" } }, }) self.assertIn("models", Tortoise._app_models_map) self.assertIsNotNone(Tortoise.get_db_client("default"))
async def run(): client = SqliteClient('example_relations.sqlite3') await client.create_connection() Tortoise.init(client) await generate_schema(client) tournament = Tournament(name='New Tournament') await tournament.save() await Event(name='Without participants', tournament_id=tournament.id).save() event = Event(name='Test', tournament_id=tournament.id) await event.save() participants = [] for i in range(2): team = Team(name='Team {}'.format(i + 1)) await team.save() participants.append(team) await event.participants.add(participants[0], participants[1]) await event.participants.add(participants[0], participants[1]) try: for team in event.participants: print(team.id) except NoValuesFetched: pass async for team in event.participants: print(team.id) for team in event.participants: print(team.id) print(await Event.filter( participants=participants[0].id, ).prefetch_related('participants', 'tournament')) print(await participants[0].fetch_related('events')) print(await Team.fetch_for_list(participants, 'events')) print(await Team.filter(events__tournament__id=tournament.id)) print(await Event.filter(tournament=tournament)) print(await Tournament.filter( events__name__in=['Test', 'Prod'], ).order_by('-events__participants__name').distinct()) print(await Event.filter(id=event.id).values('id', 'name', tournament='tournament__name')) print(await Event.filter(id=event.id).values_list('id', 'participants__name'))
async def run(): client = SqliteClient('example_basic.sqlite3') await client.create_connection() Tortoise.init(client) await generate_schema(client) event = await Event.create(name='Test') await Event.filter(id=event.id).update(name='Updated name') print(await Event.filter(name='Updated name').first()) await Event(name='Test 2').save() print(await Event.all().values_list('id', flat=True)) print(await Event.all().values('id', 'name'))
async def run(): client = SqliteClient('example_schema.sqlite3') await client.create_connection() Tortoise.init(client) await generate_schema(client) tournament = await Tournament.create(name='Test') event = await Event.create(name='Test 1', tournament=tournament, prize=100) print(event.modified) event.name = 'Test 2' await event.save() print(event.modified) await Team.create(name='test') print(await Team.all().values('name'))
async def init_for(self, module: str, safe=False) -> None: if self.engine != "tortoise.backends.sqlite": raise test.SkipTest("sqlite only") Tortoise.init( { "connections": { "default": { "engine": "tortoise.backends.sqlite", "file_path": ":memory:", } }, "apps": {"models": {"models": [module], "default_connection": "default"}}, } ) self.sqls = Tortoise.get_schema_sql(Tortoise.get_db_client("default"), safe=safe).split(";\n")
def test_default_connection_init(self): Tortoise.init({ "connections": { "default": { "engine": "tortoise.backends.sqlite", "file_path": ":memory:", } }, "apps": { "models": { "models": ["tests.testmodels"] } }, }) self.assertIn("models", Tortoise._app_models_map) self.assertIsNotNone(Tortoise.get_db_client("default"))
def test_init_wrong_connection_engine(self): with self.assertRaisesRegex(ImportError, "tortoise.backends.test"): Tortoise.init({ "connections": { "default": { "engine": "tortoise.backends.test", "file_path": ":memory:", } }, "apps": { "models": { "models": ["tests.testmodels"], "default_connection": "default" } }, })
async def run(): Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.open_connections() await Tortoise.generate_schemas() tournament = await Tournament.create(name="New Tournament", desc="great") await tournament.save() await Tournament.create(name="Second tournament") await Tournament.create(name=" final tournament ") await Event(name="Without participants", tournament_id=tournament.id).save() event = Event(name="Test", tournament_id=tournament.id) await event.save() participants = [] for i in range(2): team = Team(name=f"Team {(i + 1)}") await team.save() participants.append(team) await event.participants.add(participants[0], participants[1]) await event.participants.add(participants[0], participants[1]) print(await Tournament.all().annotate(events_count=Count("events") ).filter(events_count__gte=1)) print(await Event.filter(id=event.id).first().annotate( lowest_team_id=Min("participants__id"))) print(await Tournament.all().annotate(events_count=Count("events") ).order_by("events_count")) print(await Event.all().annotate(tournament_test_id=Sum("tournament__id") ).first()) print(await Tournament.annotate(clean_desciption=Coalesce("desc") ).filter(clean_desciption="")) print(await Tournament.annotate(trimmed_name=Trim("name") ).filter(trimmed_name="final tournament")) print(await Tournament.annotate(name_len=Length("name") ).filter(name_len__gt=len("New Tournament"))) print(await Tournament.annotate(name_lo=Lower("name") ).filter(name_lo="new tournament")) print(await Tournament.annotate(name_lo=Upper("name") ).filter(name_lo="NEW TOURNAMENT"))
def test_wrong_app_init(self): with self.assertRaisesRegex(ConfigurationError, "No app with name 'app' registered."): Tortoise.init({ "connections": { "default": { "engine": "tortoise.backends.sqlite", "file_path": ":memory:", } }, "apps": { "models": { "models": ["tests.model_setup.model_bad_rel1"], "default_connection": "default", } }, })
def test_unknown_connection(self): with self.assertRaisesRegex(ConfigurationError, 'Unknown connection "fioop"'): Tortoise.init({ "connections": { "default": { "engine": "tortoise.backends.sqlite", "file_path": ":memory:", } }, "apps": { "models": { "models": ["tests.testmodels"], "default_connection": "fioop" } }, })
def test_bad_models(self): with self.assertRaisesRegex(ConfigurationError, 'Module "tests.testmodels2" not found'): Tortoise.init({ "connections": { "default": { "engine": "tortoise.backends.sqlite", "file_path": ":memory:", } }, "apps": { "models": { "models": ["tests.testmodels2"], "default_connection": "default" } }, })
def test_empty_modules_init(self): with self.assertWarnsRegex(RuntimeWarning, 'Module "tests.model_setup" has no models'): Tortoise.init({ "connections": { "default": { "engine": "tortoise.backends.sqlite", "file_path": ":memory:", } }, "apps": { "models": { "models": ["tests.model_setup"], "default_connection": "default" } }, })