Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AC2 - gp2 (Nad, Dalia) #18

Open
wants to merge 52 commits into
base: main
Choose a base branch
from
Open

AC2 - gp2 (Nad, Dalia) #18

wants to merge 52 commits into from

Conversation

dnabilali
Copy link

No description provided.

dnabilali and others added 30 commits January 3, 2023 13:54
implemented wave 1 for the customer_routes, tests are passing
…OST /rentals/check-out to stop customer from checking out the same video twice and to display the correct due_date for the rentals
nadxelleHernandez and others added 22 commits January 5, 2023 17:17
implemented GET /videos/<video_id>/rentals and changed some code in P…
Nadbranch query parameters and paginations
…/rentals, updated video model to include available_inventory attribute, created new migration for the video model update
refactored customer routes to use the function to_dict()
Tested everything again with no problems
Wave 4 nad videos query parameters
Copy link

@kelsey-steven-ada kelsey-steven-ada left a comment

Choose a reason for hiding this comment

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

Really nice work Nad & Dalia! I've left a few comments & questions, feel free to reply here or message me on Slack if you have questions on the feedback 🙂

@@ -5,7 +5,7 @@
from dotenv import load_dotenv

db = SQLAlchemy()
migrate = Migrate()
migrate = Migrate(compare_type=True)

Choose a reason for hiding this comment

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

Just curious, was this addition to manage issues you had updating models?

Copy link
Author

Choose a reason for hiding this comment

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

we found out that if we add this optional parameter changes made to the data types of attributes for our models will be reflected in the migration. here the documentation for that: https://alembic.sqlalchemy.org/en/latest/autogenerate.html

postal_code = db.Column(db.String, nullable=False)
phone = db.Column(db.String, nullable=False)
registered_at = db.Column(db.DateTime, default=datetime.datetime.now().strftime("%a, %d %b %Y %X %z"))
videos_checked_out_count = db.Column(db.Integer, nullable=False, default=0)

Choose a reason for hiding this comment

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

In most situations, if we can derive the data we want from something else we are already storing, we should choose to do that over storing a new piece of data. If we store a piece of derivable data, we need to manually keep our related data in sync which introduces places for potential bugs, and we take up more memory for each record.

In this case, we hold videos which is a list of the videos the user currently has checked out and videos_checked_out_count. We could remove videos_checked_out_count and call len on videos anywhere we need the count.

Comment on lines +7 to +8
postal_code = db.Column(db.String, nullable=False)
phone = db.Column(db.String, nullable=False)

Choose a reason for hiding this comment

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

It isn't necessary for this project, but out in the wild we'd likely look at what the max size these strings could possibly be is and give character limits in the definition. The top answers here give some explanation of possible performance impacts: https://stackoverflow.com/questions/1962310/importance-of-varchar-length-in-mysql-table

id = db.Column(db.Integer, primary_key=True)

Choose a reason for hiding this comment

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

Another option could be to create a composite primary key from the customer_id and video_id columns. The benefit is we can store one less column for each record, but the limitation is there can only ever be one Rental record with that combination of customer and video ids.

# One possible set up
video_id = db.Column(db.Integer, db.ForeignKey('video.id'), primary_key=True, nullable=False)
customer_id = db.Column(db.Integer, db.ForeignKey('customer.id'), primary_key=True, nullable=False)

id = db.Column(db.Integer, primary_key=True, autoincrement=True, nullable=False)
title = db.Column(db.String, nullable=False)
total_inventory = db.Column(db.Integer, nullable=False)
available_inventory = db.Column(db.Integer, default=available_inventory_default)

Choose a reason for hiding this comment

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

This is another field that we could derive, this time using total_inventory and the count of current rentals with this video id.


return model_instance

def validate_request_body(request_body,required_data):

Choose a reason for hiding this comment

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

I like the flexibility of this for checking data to create & update models!

def validate_request_body(request_body,required_data):
if not request_body:
msg = "An empty or invalid json object was sent."
abort(make_response(jsonify({"details":msg}),400))

Choose a reason for hiding this comment

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

Tiny style nitpick: for best practices we'd want a space after the comma as a visual separation between the make_response arguments

new_rental = Rental(
customer_id=valid_customer.id,
video_id=valid_video.id,
due_date=datetime.now() + timedelta(days=MAX_DAYS_RENTALS))

Choose a reason for hiding this comment

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

I'm wondering if this is something that could be set as a default on the column like the registered_at attribute of the Customer model.

valid_video = validate_model(Video, request_body["video_id"])

if valid_video.available_inventory < 1:
abort(make_response(jsonify({"message":"Could not perform checkout"}), 400))

Choose a reason for hiding this comment

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

In a real life scenario, we might want to add more specific info like "Could not perform checkout: no copies available"

Comment on lines +72 to +76
try:
db.session.add(new_video)
db.session.commit()

except:

Choose a reason for hiding this comment

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

Were there errors you were running into saving new models that required the try/except here?

Copy link

@nadxelleHernandez nadxelleHernandez Jan 15, 2023

Choose a reason for hiding this comment

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

Not really. This was me being paranoid. One of my most traumatic bugs happened when the db for my app wasn't available due to network problems. It was hard for me to find why sometimes the data was saved and some other times it wasn't. So out of extra precaution, I put those there to have some info in the server logs, in case something couldn't be saved due to database problems.
However I must agree I should have had more consistency as I only did it for creating the video and it should have been part of all the functions where the database was being changed. That would include the update and delete methods for every model and the check-in, check-out endpoints for rentals.

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.

3 participants