-
Hello, First, thanks for all your docker project generators as well as the fantastic documentation. They have been super useful in getting my project off the ground. I've been following the sqlalchemy example at: https://fastapi.tiangolo.com/tutorial/sql-databases/. I'm trying to return a sqlalchemy data model, but I am getting the following error:
If I modify the fastapi specific code: and parse the sqlalchemy response into a dictionary, it works fine: @app.get("/users/{username}")
def read_user(username: str):
user = get_user(username, db_session)
user = {"name": user.id, "email": user.email}
return user Thanks again. Been loving FastAPI so far. |
Beta Was this translation helpful? Give feedback.
Replies: 9 comments
-
That's great to hear 🍰 🎉 Thanks for the report! I think I know what might be happening. Are you using the simple model from the tutorial? Or are you using the models from the full-stack project generator here?: https://github.com/tiangolo/full-stack/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/models/user.py I see those would create recursive attributes, I have to find a way to solve that specific case or document it properly. But first I want to confirm with you, how do your model looks like? Or can you share the model here?
Thanks! Awesome 😊🎉 As a note, if you are using the full-stack generator, I plan on creating a full-stack-fastapi-postgres generator equivalent to that one 😄 |
Beta Was this translation helpful? Give feedback.
-
Thanks for the quick response. My use case is pretty simple, so I just pulled the I've simplified the example a bit below for readability, but it is essentially the same. The model I am working with is straight forward and doesn't have any relationships. The model is below: from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
from sqlalchemy.dialects.postgresql import JSONB, NUMERIC, VARCHAR
Base = declarative_base()
class Summary(Base):
__tablename__ = 'full_summary'
company_name = Column(VARCHAR)
city = Column(VARCHAR)
state = Column(VARCHAR)
business_types = Column(JSONB)
total = Column(NUMERIC) And I call it with the code below: def get_company(company_name):
session = Session()
res = session.query(Summary).filter(Summary.company_name == company_name).first()
session.close()
return res
@router.get("/summary/{company_name}")
def summary(company_name: str):
company = get_company(company_name)
if company is None:
return {}
# company = {
# "name": company.company_name,
# "city": company.city,
# "state": company.state,
# "business_types": company.business_types,
# "total": company.total
# }
return company If I uncomment that dictionary, it returns fine. I also noticed that if I modify the def get_company(company_name):
session = Session()
res = session.query(Summary.name, Summary.city, Summary.business_types).\
filter(Summary.company_name == company_name).first()
session.close()
return res It will return without crashing, but it will return as a list:
Where I would expect it to return:
Sorry for the long post. Thanks for taking a look. |
Beta Was this translation helpful? Give feedback.
-
I faced the same problem by following the official documentation, but I was able to solve the problem pretty quickly. I'm assuming FastAPI can't display the data. For example: class User(Base):
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean(), default=True)
def json(self):
return {"username": self.username, "id": self.id} and router @app.get("/users/{username}")
def read_user(username: str):
user = get_user(username, db_session)
if user:
return user.json() The situation was rectified by this decision. @tiangolo please add this to documentation. |
Beta Was this translation helpful? Give feedback.
-
@nickc1 @LexSerest There was indeed a bug in the way the SQLAlchemy model was encoded. I just updated the code, tests, and docs, and released version The code for the SQL tutorial itself is being tested now to ensure SQLAlchemy works correctly and that the tutorial code is correct. The tutorial is now updated to use by default SQLite, to allow quickly testing it. But it also has instructions for the line of code that has to be changed to switch to PostgreSQL. This means that you should be able to copy the code as is, run it, and get a local file It also means that now is actually possible to return the SQLAlchemy model directly. A custom method to encode the model (like Please check and let me know if it works for you. |
Beta Was this translation helpful? Give feedback.
-
@LexSerest Thanks for the suggestion. It cleaned up my code quite a bit. @tiangolo Just upgraded to v0.3.0 and it works flawlessly. Thanks for all your work! 👏 👍 😄 |
Beta Was this translation helpful? Give feedback.
-
@nickc1 Can the ticket be closed then? |
Beta Was this translation helpful? Give feedback.
-
Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs. |
Beta Was this translation helpful? Give feedback.
@nickc1 @LexSerest There was indeed a bug in the way the SQLAlchemy model was encoded.
I just updated the code, tests, and docs, and released version
0.3.0
.The code for the SQL tutorial itself is being tested now to ensure SQLAlchemy works correctly and that the tutorial code is correct.
The tutorial is now updated to use by default SQLite, to allow quickly testing it. But it also has instructions for the line of code that has to be changed to switch to PostgreSQL.
This means that you should be able to copy the code as is, run it, and get a local file
test.db
with the SQLite database, with a FastAPI serving from it. You would most probably want to switch to PostgreSQL (or similar) for pr…