Skip to content

Commit

Permalink
Merge pull request #3 from ECE444-2020Fall/CPP-30
Browse files Browse the repository at this point in the history
Cpp 30 - Set up RDS and table schemas
  • Loading branch information
yanisakham committed Oct 26, 2020
2 parents 7fc7a15 + 38dbf80 commit 6116cab
Show file tree
Hide file tree
Showing 30 changed files with 959 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
In the root directory of the project...

1. Install node modules `yarn install` or `npm install`.
2. Install Python dependencies `yarn install-requirements` or `npm install-requirements`
2. Install Python dependencies `yarn install-requirements` or `npm install requirements`
2. Start development server `yarn start` or `npm start`.

## Next Steps
Expand Down
36 changes: 36 additions & 0 deletions server/DATABASE_README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Setting up our database

Our database is a MYSQL DB hosted on an RDS instance.
It should interact with our backend using SQLAlchemy as the db interface. SQLAlchemy is an ORM that allows us to treat our relational database like an object -- basically we query it using pythonic 'code-like' commands as opposed to creating SQL queries....

## DB related files:

### models.py :
this is where you specify tables in the database. Each table is it's own class extended from db.Model. In these classes you must specify all column attributes including attribute types, primary keys, etc.

### config.py :
This contains a config object used when intializing our app. This specifies our db endpoint, login and configs for setting up the migrations folder.

### migrations/ :
This is how we track changes to our database. Everytime we want to change the schema of our db, we run a migration and update the db.

### app/__init__.py:
During initialization we create an SQLAlchemy object and our migrations object. the SQLAlchemy object (db) is what we use in server.py to query and call the database.

## Setup

Initialize database (I've already done this for us ): `flask db init`

Create a migration: `flask db migrate -m "message specifying what you changed"`

Update the database: `flask db upgrade`

*Note: making the migration will generate migration files in the migration folder specifying the new version of our database. However, this does not modify our real database. To actually 'push' the change, you must run the upgrade command.


## Examples

I've created 3 endpoints in server.py to show how you can add/remove entries in a database. The examples use our User table; each example should be fairly straight forward.



24 changes: 24 additions & 0 deletions server/app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

# ~ Databases ~ #
db = SQLAlchemy() #<-Initialize database object
migrate = Migrate() #<-Initialize migration object

def create_app():
"""Construct core application"""
application = Flask(__name__)

# Pull from config file
application.config.from_object('config.Config')

# Initailize database
db.init_app(application) #<- This will get called in our models.py file
migrate.init_app(application, db) #<- Migration directory

return application

app = create_app()
# ~ Import database schemas ~ #
from app import models
9 changes: 9 additions & 0 deletions server/app/model_schemas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .favourites_list import FavouritesList
from .pantry_list import PantryList
from .recipe import Recipe
from .recipe_cart import RecipeCart
from .recipe_ingredient import RecipeIngredient
from .shopping_list import ShoppingList
from .user import User
from .user_notes import UserNotes
from .user_rating import UserRating
21 changes: 21 additions & 0 deletions server/app/model_schemas/favourites_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from app import db
from sqlalchemy_utils import UUIDType

class FavouritesList(db.Model):
__tablename__ = 'favourites_list'
user_id = db.Column(
UUIDType(),
db.ForeignKey('user.user_id'),
nullable=False,
primary_key=True
)
recipe_id = db.Column(
UUIDType(),
db.ForeignKey('recipe.recipe_id'),
nullable=False,
primary_key=True
)

def __init__(self, user_id, recipe_id):
self.user_id = user_id
self.recipe_id = recipe_id
21 changes: 21 additions & 0 deletions server/app/model_schemas/pantry_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from app import db
from constants import CONSTANTS
from sqlalchemy_utils import UUIDType

class PantryList(db.Model):
__tablename__ = 'pantry_list'
user_id = db.Column(
UUIDType(),
db.ForeignKey('user.user_id'),
nullable=False,
primary_key=True
)
ingredient_name = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_INGREDIENT_NAME_LEN']),
primary_key=True,
nullable=False
)

def __init__(self, user_id, ingredient_name):
self.user_id = user_id
self.ingredient_name = ingredient_name
78 changes: 78 additions & 0 deletions server/app/model_schemas/recipe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from app import db
import uuid
from constants import CONSTANTS
from sqlalchemy_utils import UUIDType

class Recipe(db.Model):
__tablename__ = 'recipe'
recipe_id = db.Column(
UUIDType(),
primary_key=True,
default=uuid.uuid4,
nullable=False
)

recipe_name = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_RECIPE_NAME_LEN']),
nullable=False
)

cuisine = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_CUISINE_LEN']),
nullable=False
)

instructions = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_INSTRUCTION_LEN']),
nullable=False
)

time_to_cook_in_minutes = db.Column(
db.Integer,
nullable=False
)

servings = db.Column(
db.Integer,
nullable=False
)

calories = db.Column(
db.Float,
nullable=False
)

protein = db.Column(
db.Float,
nullable=False
)


carbs = db.Column(
db.Float,
nullable=False
)

fat = db.Column(
db.Float,
nullable=False
)

def __init__(
self, recipe_id, recipe_name, cuisine, instructions,
time_to_cook_in_minutes, servings, calories, protein, carbs, fat):
self.recipe_id = recipe_id
self.recipe_name = recipe_name
self.cuisine = cuisine
self. instructions = instructions
self.time_to_cook_in_minutes = time_to_cook_in_minutes
self.servings = servings
self.calories = calories
self.protein = protein
self.carbs = carbs
self.fat = fat





21 changes: 21 additions & 0 deletions server/app/model_schemas/recipe_cart.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from app import db
from sqlalchemy_utils import UUIDType

class RecipeCart(db.Model):
__tablename__ = 'recipe_cart'
user_id = db.Column(
UUIDType(),
db.ForeignKey('user.user_id'),
nullable=False,
primary_key=True
)
recipe_id = db.Column(
UUIDType(),
db.ForeignKey('recipe.recipe_id'),
nullable=False,
primary_key=True
)

def __init__(self, user_id, recipe_id):
self.user_id = user_id
self.recipe_id = recipe_id
31 changes: 31 additions & 0 deletions server/app/model_schemas/recipe_ingredient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from app import db
from constants import CONSTANTS
from sqlalchemy_utils import UUIDType

class RecipeIngredient(db.Model):
__tablename__ = 'recipe_ingredient'
user_id = db.Column(
UUIDType(),
db.ForeignKey('user.user_id'),
nullable=False,
primary_key=True
)
ingredient_name = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_INGREDIENT_NAME_LEN']),
nullable=False,
primary_key=True
)
amount = db.Column(
db.Float,
nullable=False
)
unit_of_measurement = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_MEASUREMENT_UNIT_LEN'])
)

def __init__(self, user_id, ingredient_name, amount, unit_of_measurement):
self.user_id = user_id
self.ingredient_name = ingredient_name
self.amount = amount
self.unit_of_measurement = unit_of_measurement

22 changes: 22 additions & 0 deletions server/app/model_schemas/shopping_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from app import db
from constants import CONSTANTS
from sqlalchemy_utils import UUIDType

class ShoppingList(db.Model):
__tablename__ = 'shopping_list'
user_id = db.Column(
UUIDType(),
db.ForeignKey('user.user_id'),
nullable=False,
primary_key=True
)
item_name = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_INGREDIENT_NAME_LEN']),
primary_key=True,
nullable=False
)

def __init__(self, user_id, item_name):
self.user_id = user_id
self.item_name = item_name

28 changes: 28 additions & 0 deletions server/app/model_schemas/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from app import db
import uuid
from constants import CONSTANTS
from sqlalchemy_utils import UUIDType

class User(db.Model):
__tablename__ = 'user'
user_id = db.Column(
UUIDType(),
primary_key=True,
default=uuid.uuid4,
nullable=False
)

username = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_USERNAME_LEN']),
nullable=False
)

password = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_PASSWORD_LEN']),
nullable=False
)

def __init__(self, username, password):
self.username = username
self.password = password

27 changes: 27 additions & 0 deletions server/app/model_schemas/user_notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from app import db
from constants import CONSTANTS
from sqlalchemy_utils import UUIDType

class UserNotes(db.Model):
__tablename__ = 'user_notes'
user_id = db.Column(
UUIDType(),
db.ForeignKey('user.user_id'),
nullable=False,
primary_key=True
)
recipe_id = db.Column(
UUIDType(),
db.ForeignKey('recipe.recipe_id'),
nullable=False,
primary_key=True
)
user_notes = db.Column(
db.String(CONSTANTS['DB_SCHEMA']['MAX_INSTRUCTION_LEN']),
nullable=False
)

def __init__(self, user_id, recipe_id, user_notes):
self.user_id = user_id
self.recipe_id = recipe_id
self.user_notes = user_notes
27 changes: 27 additions & 0 deletions server/app/model_schemas/user_rating.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from app import db
from constants import CONSTANTS
from sqlalchemy_utils import UUIDType

class UserRating(db.Model):
__tablename__ = 'user_rating'
user_id = db.Column(
UUIDType(),
db.ForeignKey('user.user_id'),
nullable=False,
primary_key=True
)
recipe_id = db.Column(
UUIDType(),
db.ForeignKey('recipe.recipe_id'),
nullable=False,
primary_key=True
)
user_rating = db.Column(
db.Float,
nullable=False
)

def __init__(self, user_id, recipe_id, user_rating):
self.user_id = user_id
self.recipe_id = recipe_id
self.user_rating = user_rating
1 change: 1 addition & 0 deletions server/app/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from app.model_schemas import *
14 changes: 14 additions & 0 deletions server/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import os
from constants import CONSTANTS

# Absolute directory path
basedir = os.path.abspath(os.path.dirname(__file__))

# ~ Create config object ~ #
class Config(object):
# ~~ Migration Repository ~~ #
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repo')
SQLALCHEMY_DATABASE_URI = CONSTANTS['DATABASE_URL']
SQLALCHEMY_TRACK_MODIFICATIONS = False,
JSONIFY_PRETTYPRINT_REGULAR = True

10 changes: 10 additions & 0 deletions server/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,15 @@
'ENDPOINT': {
'MASTER_DETAIL': '/api/masterdetail',
'LIST': '/api/list',
},
'DATABASE_URL': 'mysql+pymysql://admin:ece444iscool@chefcopilotdb.cwgapkme6bda.us-east-2.rds.amazonaws.com/chefcopilot',
'DB_SCHEMA': {
'MAX_USERNAME_LEN': 120,
'MAX_PASSWORD_LEN': 100,
'MAX_INGREDIENT_NAME_LEN': 100,
'MAX_RECIPE_NAME_LEN': 100,
'MAX_CUISINE_LEN': 50,
'MAX_INSTRUCTION_LEN': 500,
'MAX_MEASUREMENT_UNIT_LEN': 50
}
}
Loading

0 comments on commit 6116cab

Please sign in to comment.