Restaurant Info Application
a scalable restaurant recommendation web application on Google Cloud Platform
Restaurant Review Application
This Flask-based web application allows users to sign up, log in, and manage their profiles, as well as review restaurants and search for restaurants and dishes based on various criteria.
ER Diagram
Features
User Authentication
- Sign Up: Users can create a new account by providing a username, password, and their taste preferences.
- Login: Users can log in using their credentials.
- Logout: Allows users to log out of the application.
Restaurant Reviews
- Add Review: Logged-in users can add reviews for restaurants, including a star rating and text.
- Search Restaurant: Users can search for restaurants based on category, city, and minimum star rating. Additional filters include restaurant name, postal code, and crime rate in the area.
Dish Management
- Search Dish: Search for dishes by name across different restaurants and retrieve related crime data.
- Modify Dish Data: Users with appropriate permissions can add, delete, or update dish details in the database.
- List All Dishes: Displays all dishes in the database.
Advanced Features
- Transaction: Demonstration of a complex transaction in SQL, retrieving detailed information about restaurants and associated crime data based on location and rating filters.
Setup
Prerequisites
- Python 3.x
- Flask
- Flask-MySQLdb
- PyYAML
- A MySQL server
Installation
- Clone the repository:
git clone [repository_url] cd [repository_directory] - Install dependencies:
pip install flask flask-mysqldb pyyaml werkzeug - Configure the database:
- Modify the
db.yamlfile under the project directory to include your MySQL database credentials.
- Modify the
Running the Application
- Start the Flask application:
python app.py - Open a web browser and navigate to
http://127.0.0.1:5000/to access the application.
Usage
- Home Page: Accessible at the root URL (
/). Redirects to the login page if the user is not logged in. - Login/Signup: Use the login/signup forms to access user-specific functionalities.
- Review and Search: After logging in, users can add reviews, search for restaurants, and manage dish data through the navigation menu.
Required Advanced SQL Commands
DELIMITER //
CREATE PROCEDURE GetRestaurantInfoWithCrime(
IN location_name VARCHAR(31),
IN min_rating REAL
)
BEGIN
-- Declare variable to check if valid restaurants exist
DECLARE valid_restaurant_exists BOOLEAN DEFAULT FALSE;
-- Start the transaction
START TRANSACTION;
-- Check if the input min_rating is within a valid range
IF min_rating >= 0 AND min_rating <= 5 THEN
-- Query to get restaurant information based on location and minimum rating
SELECT r.RestaurantName, AVG(rev.Stars) AS AvgRating
FROM Restaurant r
INNER JOIN Review rev ON r.RestaurantId = rev.RestaurantId
INNER JOIN Location loc ON r.LocationId = loc.LocationId
WHERE loc.City = location_name
GROUP BY r.RestaurantId
HAVING AvgRating >= min_rating
ORDER BY AvgRating DESC;
SELECT c.Type AS Crime_Type, COUNT(*) AS Crime_Count
FROM Crime c
INNER JOIN Location loc ON c.LocationId = loc.LocationId
WHERE loc.City = location_name
GROUP BY c.Type;
ELSE
-- If min_rating is not valid, output an error or a specific message
SELECT 'Invalid rating. Please provide a rating between 0 and 5.' AS ErrorMessage;
END IF;
-- Commit the transaction
COMMIT;
END //
DELIMITER ;
DELIMITER //
CREATE TRIGGER set_default_review_text
BEFORE INSERT ON Review
FOR EACH ROW
BEGIN
IF TRIM(NEW.Text) IS NULL OR TRIM(NEW.Text) = '' THEN
IF NEW.Stars >= 4 THEN
SET NEW.Text = 'System default Great';
ELSEIF NEW.Stars BETWEEN 2 AND 3 THEN
SET NEW.Text = 'System default Normal';
ELSE
SET NEW.Text = 'System default Bad';
END IF;
END IF;
-- Additionally, update the average star rating in the Restaurant table
UPDATE Restaurant
SET Stars = (SELECT AVG(Stars) FROM Review WHERE RestaurantId = NEW.RestaurantId)
WHERE RestaurantId = NEW.RestaurantId;
END;
//
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE WithDishRestaurantInfo(
IN dishName VARCHAR(127)
)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE vRestaurantId INT;
DECLARE vRestaurantName VARCHAR(255);
DECLARE vCity VARCHAR(127);
DECLARE vState VARCHAR(127);
DECLARE cur CURSOR FOR
SELECT
r.RestaurantId,
r.RestaurantName,
l.City,
l.State
FROM Dish d
LEFT JOIN Restaurant r ON d.RestaurantId = r.RestaurantId
LEFT JOIN Location l ON r.LocationId = l.LocationId
WHERE d.Name LIKE CONCAT('%', dishName, '%');
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- Check if the input dish name is not empty
IF TRIM(dishName) = '' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Dish name cannot be empty';
ELSE
OPEN cur;
read_loop: LOOP
FETCH cur INTO vRestaurantId, vRestaurantName, vCity, vState;
IF done THEN
LEAVE read_loop;
END IF;
-- Output current restaurant information
SELECT vRestaurantId, vRestaurantName, vCity, vState;
-- Execute second query for the current restaurant
SELECT
c.Type AS CrimeType,
SUM(c.Count) AS TotalIncidents,
AVG(c.Count) AS AverageIncidents
FROM Crime c
JOIN Occurrence o ON c.CrimeId = o.CrimeId
JOIN Restaurant r ON r.RestaurantId = o.RestaurantId
WHERE r.RestaurantId = vRestaurantId
GROUP BY c.Type
ORDER BY TotalIncidents DESC;
END LOOP;
CLOSE cur;
END IF;
END$$
DELIMITER ;