fromtypingimportListimportdatabasesimportpytestimportsqlalchemyfromfastapiimportFastAPIfromstarlette.testclientimportTestClientimportormarfromtests.settingsimportDATABASE_URLapp=FastAPI()metadata=sqlalchemy.MetaData()database=databases.Database(DATABASE_URL,force_rollback=True)app.state.database=database# define startup and shutdown events@app.on_event("startup")asyncdefstartup()->None:database_=app.state.databaseifnotdatabase_.is_connected:awaitdatabase_.connect()@app.on_event("shutdown")asyncdefshutdown()->None:database_=app.state.databaseifdatabase_.is_connected:awaitdatabase_.disconnect()# define ormar modelsclassCategory(ormar.Model):classMeta:tablename="categories"metadata=metadatadatabase=databaseid:ormar.Integer(primary_key=True)name:ormar.String(max_length=100)classItem(ormar.Model):classMeta:tablename="items"metadata=metadatadatabase=databaseid:ormar.Integer(primary_key=True)name:ormar.String(max_length=100)category:ormar.ForeignKey(Category,nullable=True)# define endpoints in fastapi@app.get("/items/",response_model=List[Item])asyncdefget_items():items=awaitItem.objects.select_related("category").all()# not that you can return a model directly - fastapi will json-ize itreturnitems@app.post("/items/",response_model=Item)asyncdefcreate_item(item:Item):# note how ormar methods like save() are available streight out of the boxawaititem.save()returnitem@app.post("/categories/",response_model=Category)asyncdefcreate_category(category:Category):awaitcategory.save()returncategory@app.put("/items/{item_id}")asyncdefget_item(item_id:int,item:Item):# you can work both with item_id or itemitem_db=awaitItem.objects.get(pk=item_id)returnawaititem_db.update(**item.dict())@app.delete("/items/{item_id}")asyncdefdelete_item(item_id:int,item:Item):item_db=awaitItem.objects.get(pk=item_id)return{"deleted_rows":awaititem_db.delete()}# here is a sample test to check the working of the ormar with fastapideftest_all_endpoints():# note that TestClient is only sync, don't use asyns hereclient=TestClient(app)# note that you need to connect to database manually# or use client as contextmanagerwithclientasclient:response=client.post("/categories/",json={"name":"test cat"})category=response.json()response=client.post("/items/",json={"name":"test","id":1,"category":category})item=Item(**response.json())assertitem.pkisnotNoneresponse=client.get("/items/")items=[Item(**item)foriteminresponse.json()]assertitems[0]==itemitem.name="New name"response=client.put(f"/items/{item.pk}",json=item.dict())assertresponse.json()==item.dict()response=client.get("/items/")items=[Item(**item)foriteminresponse.json()]assertitems[0].name=="New name"response=client.delete(f"/items/{item.pk}",json=item.dict())assertresponse.json().get("deleted_rows","__UNDEFINED__")!="__UNDEFINED__"response=client.get("/items/")items=response.json()assertlen(items)==0