Skip to content

library management solution#636

Open
StrawHato wants to merge 10 commits into
mate-academy:mainfrom
StrawHato:develop
Open

library management solution#636
StrawHato wants to merge 10 commits into
mate-academy:mainfrom
StrawHato:develop

Conversation

@StrawHato
Copy link
Copy Markdown

No description provided.

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Great job on the overall structure of your FastAPI application! The code is well-organized into separate modules for models, schemas, and CRUD operations. However, I'm requesting a couple of changes to address critical issues that prevent the application from meeting all requirements.

First, the application is missing the logic to create the database tables on startup. This is a core requirement, and without it, the API will not function. You can fix this in main.py by importing your models and engine, then calling models.Base.metadata.create_all(bind=engine) before the app starts.

Second, the endpoint for creating a book does not validate if the provided author_id exists. This leads to an unhandled 500 error if an invalid ID is used. To fix this, you should first check if the author exists and raise an HTTPException with a 404 status if they are not found.

Once these two issues are resolved, your project will be in great shape!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This upgrade function is empty. Based on the migration's name, it seems you intended to add lengths to the string columns in your models. You'll need to use op.alter_column() to apply these changes to the database schema.

def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
pass
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The downgrade function is also empty. It should contain the logic to reverse the changes made in the upgrade function. If upgrade adds string lengths, downgrade should remove them.

# ### commands auto generated by Alembic - please adjust! ###
op.create_table('author',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name column is missing the string length (255) defined in the Author model. Also, consider making this column non-nullable (nullable=False), as an author's name is a key identifier and should generally not be optional.

op.create_table('author',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('bio', sa.String(), nullable=False),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This column is missing the string length (512) that is specified in the Author model in models.py.

op.create_index(op.f('ix_author_id'), 'author', ['id'], unique=False)
op.create_table('book',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('title', sa.String(), nullable=True),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The title column is missing the string length (255) from the Book model. It's also recommended to make the title of a book non-nullable (nullable=False) for better data integrity.

Comment thread main.py
Comment on lines +41 to +42
def create_book(book: schemas.BookCreate, db: Session = Depends(get_db)):
return crud.create_book(db=db, book=book)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This endpoint doesn't check if the author_id provided in the book payload corresponds to an existing author. If an invalid author_id is passed, the database will raise a foreign key constraint error, resulting in an unhandled 500 error. It would be better to first verify the author exists and return a 404 error if not found.

Comment thread models.py
__tablename__ = "author"

id = Column(Integer, primary_key=True, index=True)
name = Column(String(255), unique=True)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure every author has a name, it's good practice to make this column non-nullable. You can do this by adding nullable=False, similar to how the bio field is defined.

Comment thread models.py
__tablename__ = "book"

id = Column(Integer, primary_key=True, index=True)
title = Column(String(255))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A book's title is typically a required piece of information. Consider making this column non-nullable by adding nullable=False to prevent creating book records without a title.

Comment thread models.py
title = Column(String(255))
summary = Column(String(512))
publication_date = Column(Date)
author_id = Column(Integer, ForeignKey("author.id"))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This foreign key is currently nullable, which means a book can exist without being associated with an author. To enforce the relationship and prevent 'orphan' books, you should make this column non-nullable by adding nullable=False.

Comment thread crud.py
return db.query(models.Author).filter(models.Author.id == author_id).first()


def get_books_list(db: Session, author_id: int, skip: int = 0, limit: int = 10):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type hint for author_id is int, but this parameter can be None when the /books/ endpoint is called without an author_id query parameter (as defined in main.py). To accurately reflect this, you should update the type hint to int | None.

Copy link
Copy Markdown

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Excellent work on this submission! You've successfully addressed all the previous feedback, and the application now meets all the core requirements. The database tables are created correctly on startup, and author validation is properly implemented.

I am approving your solution. I did find a couple of minor areas for future improvement, though they are not blockers:

  • In crud.py, the type hint for author_id in the get_books_list function could be int | None to perfectly match its usage in main.py.
  • The migration file alembic/versions/fe5305001d25_add_author_and_book_models.py doesn't specify lengths for the String columns, which is inconsistent with your models. While not an issue here since you use create_all, it's good practice for migrations to be precise.

Great job getting everything working correctly!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Footnotes

  1. Rate AI review example

Comment on lines +26 to +35
sa.Column('name', sa.String(), nullable=True),
sa.Column('bio', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_index(op.f('ix_author_id'), 'author', ['id'], unique=False)
op.create_table('book',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('title', sa.String(), nullable=True),
sa.Column('summary', sa.String(), nullable=True),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This migration doesn't specify the lengths for the String columns (name, bio, title, summary). This is inconsistent with your models.py file, which defines specific lengths (e.g., String(255)).

While SQLite might not enforce this, it's important for migrations to accurately reflect the models for consistency and portability to other database systems. Please update the sa.String() calls here to include the lengths defined in your models.

Comment thread crud.py
return db.query(models.Author).filter(models.Author.id == author_id).first()


def get_books_list(db: Session, author_id: int, skip: int = 0, limit: int = 10):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type hint for author_id is int, but the function logic correctly handles the case where it might be None (on line 34). The corresponding endpoint in main.py also defines this parameter as optional (int | None).

To ensure consistency and accurate type hinting, please update the signature to def get_books_list(db: Session, author_id: int | None, skip: int = 0, limit: int = 10):.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants