"""
These imports define the key objects
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
"""
These object and definitions are used throughout the Jupyter Notebook.
"""
# Setup of key Flask object (app)
app = Flask(__name__)
# Setup SQLAlchemy object and properties for the database (db)
database = 'sqlite:///countries.db' # path and filename of database
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = database
app.config['SECRET_KEY'] = 'SECRET_KEY'
db = SQLAlchemy()
# This belongs in place where it runs once per project
db.init_app(app)
""" database dependencies to support sqlite examples """
import datetime
from datetime import datetime
import json
from sqlalchemy.exc import IntegrityError
from werkzeug.security import generate_password_hash, check_password_hash
''' Tutorial: https://www.sqlalchemy.org/library.html#tutorials, try to get into a Python shell and follow along '''
# Define the User class to manage actions in the 'users' table
# -- Object Relational Mapping (ORM) is the key concept of SQLAlchemy
# -- a.) db.Model is like an inner layer of the onion in ORM
# -- b.) User represents data we want to store, something that is built on db.Model
# -- c.) SQLAlchemy ORM is layer on top of SQLAlchemy Core, then SQLAlchemy engine, SQL
class Country(db.Model):
__tablename__ = 'countries' # table name is plural, class name is singular
# Define the User schema with "vars" from object
id = db.Column(db.Integer, primary_key=True)
_country = db.Column(db.String(255), unique=False, nullable=False)
_cid = db.Column(db.String(255), unique=True, nullable=False)
_continent = db.Column(db.String(255), unique=False, nullable=False)
_population = db.Column(db.Integer, unique=False, nullable=False)
#_population = db.Column(db.Integer, unique=False, nullable=False)
# constructor of a User object, initializes the instance variables within object (self)
def __init__(self, country, cid, continent, population):
self._country = country # variables with self prefix become part of the object,
self._cid = cid
self._continent = continent
self._population = population
#self._population = population
# a name getter method, extracts name from object
@property
def country(self):
return self._country
# a setter function, allows name to be updated after initial object creation
@country.setter
def country(self, country):
self._country = country
# a getter method, extracts uid from object
@property
def cid(self):
return self._cid
# a setter function, allows uid to be updated after initial object creation
@cid.setter
def cid(self, cid):
self._cid = cid
# check if uid parameter matches user id in object, return boolean
def is_cid(self, cid):
return self._cid == cid
@property
def continent(self):
return self._continent
# a setter function, allows name to be updated after initial object creation
@continent.setter
def continent(self, continent):
self._continent = continent
@property
def population(self):
return self._population
# a setter function, allows name to be updated after initial object creation
@population.setter
def population(self, population):
self._population = population
# output content using str(object) is in human readable form
# output content using json dumps, this is ready for API response
def __str__(self):
return json.dumps(self.read())
# CRUD create/add a new record to the table
# returns self or None on error
def create(self):
try:
# creates a person object from User(db.Model) class, passes initializers
db.session.add(self) # add prepares to persist person object to Users table
db.session.commit() # SqlAlchemy "unit of work pattern" requires a manual commit
return self
except IntegrityError:
db.session.remove()
return None
# CRUD read converts self to dictionary
# returns dictionary
def read(self):
return {
"id": self.id,
"country": self.country,
"cid": self.cid,
"continent": self.continent,
"population": self.population,
}
# CRUD update: updates user name, password, phone
# returns self
def update(self, country="", continent="", population=""):
"""only updates values with length"""
if len(country) > 0:
self.country = country
if len(continent) > 0:
self.continent = continent
if len(population) > 0:
self.population = population
db.session.merge(self)
db.session.commit()
return self
# CRUD delete: remove self
# None
def delete(self):
db.session.delete(self)
db.session.commit()
return None
"""Database Creation and Testing """
# Builds working data for testing
# SQLAlchemy extracts single user from database matching User ID
def find_by_cid(cid):
with app.app_context():
place = Country.query.filter_by(_cid=cid).first()
return place # returns user object
# Check credentials by finding user and verify password
def check_credentials(cid, continent):
# query email and return user record
place = find_by_cid(cid)
if place == None:
return False
if (place.is_continent(continent)):
return True
return False
def find_by_country(country):
with app.app_context():
place = Country.query.filter_by(_country=country).first()
return place # returns user object
# Check credentials by finding user and verify password
def check_credentials(country):
# query email and return user record
place = find_by_cid(country)
if place == None:
return False