-
Hello, I'm trying to use ormar to make a very simple API for a Quiz app. My issue stems from the If I then try to get the quiz with its id, the list of linked questions (and by such answers) will be empty. Here's an example of the data passed to the {
"title": "Example",
"questions": [
{
"question": "A question",
"answers": [
{
"text": "Answer 1",
"correct": true
},
{
"text": "Answer 2",
"correct": false
},
{
"text": "Answer 3",
"correct": false
},
{
"text": "Answer 4",
"correct": false
}
]
}
]
} And here's what it returns {
"id": "5f944f7ee90e4d",
"title": "Example",
"questions": [
{
"id": null,
"question": "A question",
"answers": [
{
"id": null,
"text": "Answer 1",
"correct": true
},
{
"id": null,
"text": "Answer 2",
"correct": false
},
{
"id": null,
"text": "Answer 3",
"correct": false
},
{
"id": null,
"text": "Answer 4",
"correct": false
}
],
"quiz": {
"id": "5f944f7ee90e4d",
"title": "Example"
}
}
]
} The quiz is created without any problems, but the questions and answers aren't accessible My code is as follows: import databases
import sqlalchemy
import uvicorn
from fastapi import FastAPI, HTTPException
import secrets
import random
import ormar
from ormar import Integer, String, Boolean, ForeignKey
app = FastAPI()
metadata = sqlalchemy.MetaData()
database = databases.Database(url)
app.state.database = database
@app.on_event("startup")
async def startup() -> None:
database_ = app.state.database
if not database_.is_connected:
await database_.connect()
@app.on_event("shutdown")
async def shutdown() -> None:
database_ = app.state.database
if database_.is_connected:
await database_.disconnect()
class Quiz(ormar.Model):
class Meta:
tablename = "quiz"
database = database
metadata = metadata
id: str = String(primary_key=True, index=True, max_length=15, default='')
title: str = String(max_length=100, nullable=False)
class Question(ormar.Model):
class Meta:
tablename = "question"
database = database
metadata = metadata
id: int = Integer(primary_key=True, autoincrement=True)
question: str = String(max_length=150, nullable=False)
quiz: Quiz = ForeignKey(Quiz)
class Answer(ormar.Model):
class Meta:
tablename = "answer"
database = database
metadata = metadata
id: int = Integer(primary_key=True, autoincrement=True)
text: str = String(max_length=100, nullable=False)
correct: bool = Boolean(nullable=False)
question: Question = ForeignKey(Question)
@app.get("/quiz/random", response_model=Quiz)
async def get_random_quiz():
# ormar doesn't yet support func.random() in order_by
quizs = await Quiz.objects.all()
return random.choice(quizs)
@app.get("/quiz/{quiz_id}", response_model=Quiz)
async def get_quiz_with_id(quiz_id: str):
try:
quiz = await Quiz.objects.get(pk=quiz_id)
except ormar.exceptions.NoMatch:
raise HTTPException(status_code=404, detail="Quiz not found")
return quiz
@app.post("/quiz/create", response_model=Quiz)
async def create_quiz(quiz: Quiz):
# random hex id for the quiz
new_id = secrets.token_hex(7)
while True:
# Verify that the generated hex id isn't already assigned
try:
await Quiz.objects.get(pk=new_id)
new_id = secrets.token_hex(7)
except ormar.exceptions.NoMatch:
break
quiz.id = new_id
await quiz.save()
return quiz
if __name__ == "__main__":
# Create DB tables on first run
# engine = sqlalchemy.create_engine(url)
# metadata.create_all(engine)
# to play with API run the script and visit http://127.0.0.1:8000/docs
uvicorn.run(app, host="127.0.0.1", port=8000) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Otherwise, child models are not saved and you get back unsaved data (that's why they are missing the pk column) |
Beta Was this translation helpful? Give feedback.
save
saves only the main model, to save the whole tree including relations you need to usesave_related
https://collerek.github.io/ormar/models/methods/#save_related.Otherwise, child models are not saved and you get back unsaved data (that's why they are missing the pk column)