This is the main.py script that does most of the work of Adding movies (Movie objects) as well as modifying and removing:
from flask import Flask, render_template, request, flash, url_for, redirect
import sqlite3
from datetime import date
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from movie import Movie
app = Flask(__name__)
app.secret_key = "LOL"
Base = declarative_base()
engine = create_engine('sqlite:///adatabase.db', connect_args={'check_same_thread': False}, echo=True)
Base.metadata.create_all(engine)
Base.metadata.bind = engine
Session = (sessionmaker(bind=engine)) #scoped_session
Base.metadata.create_all(engine)
session = Session()
@app.route('/')
@app.route('/home')
def home():
return render_template('home.html')
@app.route('/form', methods = ['POST','GET'])
def form():
try:
if request.method == 'POST':
title = request.form['title']
release_date = request.form['release_date']
print(release_date)
session.add(Movie(title,date(int(release_date.split('-')[0]),int(release_date.split('-')[1]),int(release_date.split('-')[2]))))
session.commit()
session.close()
return redirect(url_for('table'))
except:
flash("An error occured while writing to database")
return redirect(url_for('home'))
return render_template('form.html', title = "Form")
@app.route('/table')
def table():
con = sqlite3.connect('adatabase.db')
con.row_factory = sqlite3.Row
cur = con.cursor()
cur.execute('select * from movies')
movies = cur.fetchall()
return render_template('table.html',movies = movies, title = "Movies")
@app.route('/delete/<int:post_id>')
def delete(post_id):
query = session.query(Movie).filter(Movie.id == post_id).first()
session.delete(query)
session.commit()
session.close()
return redirect(url_for('table'))
@app.route('/modify/<int:post_id>', methods = ['POST','GET'])
def modify(post_id):
query = session.query(Movie).filter(Movie.id == post_id).first()
if request.method == 'POST':
title = request.form['title']
release_date = request.form['release_date']
session.delete(query)
session.add(Movie(title,date(int(release_date.split('-')[0]),int(release_date.split('-')[1]),int(release_date.split('-')[2]))))
session.commit()
session.close()
return redirect(url_for('table'))
return render_template('edit.html',num = post_id,title = query.title,date = query.release_date)
if __name__ == '__main__':
app.run(debug = True)
I have a Movie class defined in another script movie.py:
from sqlalchemy import Column, String, Integer, Date, Table, ForeignKey
from sqlalchemy.orm import relationship
from base import Base
movies_actors_association = Table(
'movies_actors', Base.metadata,
Column('movie_id', Integer, ForeignKey('movies.id')),
Column('actor_id', Integer, ForeignKey('actors.id'))
)
class Movie(Base):
__tablename__ = 'movies'
id = Column(Integer, primary_key=True)
title = Column(String)
release_date = Column(Date)
actors = relationship('Actor',secondary=movies_actors_association)
def __init__(self,title,release_date):
self.title = title
self.release_date = release_date
def __repr__(self):
return self.title
Finally, I have 5 HTML files that I think would just clutter up the post (if it isn't already) that are just home, form, table, edit, and base (the one that all of them extend, containing hyperlinks to all other pages).
The library works great. I was having an SQLAlchemy check_same_thread issue but I've added connect_args={'check_same_thread': False}, echo=True) to the engine=create_engine() and now it runs smoothly.
I know that I should probably have several files in which I do databases, classes, page switching and such but I'm not sure about the exact structure. It also feels like I'm missing some things as some example code I've seen uses db = SQLAlchemy(app) but others just use the session and engine.