Quantcast
Viewing latest article 1
Browse Latest Browse All 3

Answer by 301_Moved_Permanently for A simple library using Flask and SQLAlchemy

Your database management is kind of a mess:

  • SQLAlchemy recommend to keep your sessions scope the same than your requests scope;
  • Having a single, global, session and closing it after a request mean that you can only ever make a single request for the whole lifetime of your application (which is not very useful);
  • (I suspect that because of that) You mix using SQLAlchemy sessions and plain sqlite connection, this is bad as a single tool should perform all these operations;
  • You mix table creation with application operations, these should be separated into two different scripts/task: your web server operate on the table, and an administration task (either by hand or with a dedicated script) is responsible for creating them beforehand.

For simplification of these tasks, a library have been developed: Flask-SQLAlchemy

You can have the following layout:

movie.py

from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class Movie(db.Model):    id = db.Column(db.Integer, primary_key=True)    title = db.Column(db.String, nullable=False)    release_date = db.Column(db.Date, nullable=False)# I’ll let you manage actors accordingly

main.py

from flask import Flask, render_template, request, flash, url_for, redirectfrom movie import Movie, dbapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///adatabase.db'db.init_app(app)# regular route definitionsif __name__ == '__main__':    app.run(debug=True)

And then, the table creation can simply be done by launching into your Python interpreter and doing:

>>> from movie import db>>> from main import app>>> app.app_context().push()>>> db.create_all()

No need to embed this logic into your web-server. Or, at the very least, put it into a function in your main.py, you don't have to run this every time you launch your server.


Now to the part about your web server. The kind of operations you display here is know as CRUD. This usually requires two kind of routes:

  1. A general route to list all items of a kind and to create new ones;
  2. A specific route to manage a single element (read, update, delete).

The general route usually respond to GET and POST, the specific one usually respond to GET, PUT and DELETE.

A rough sketch of the application would be:

from datetime import datetimefrom contextlib import suppressfrom flask import Flask, render_template, request, redirect, url_forfrom movie import Movie, dbapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///adatabase.db'db.init_app(app)@app.route('/', methods=['GET'])@app.route('/movies', methods=['POST', 'GET'])def movies():    if request.method == 'POST':        title = request.form['title']        release_date = request.form['release_date']        db.session.add(Movie(title, parse_release_date(release_date)))        db.session.commit()    movies = Movie.query.all()    return render_template('movies.html', movies=movies)@app.route('/movies/<int:post_id>', methods=['GET', 'PUT', 'DELETE'])def movie(post_id):    the_movie = Movie.query.filter(Movie.id == post_id).first()    if request.method == 'DELETE':        db.session.delete(the_movie)        db.session.commit()        return redirect(url_for('movies'))    if request.method == 'PUT':        with suppress(KeyError):            the_movie.title = request.form['title']        with suppress(KeyError):            the_movie.release_date = parse_release_date(request.form['release_date'])        db.session.commit()    return render_template('single_movie.html', movie=the_movie)def parse_release_date(date):    parsed_date = datetime.strptime(date, '%Y-%m-%d')    return parsed_date.date()if __name__ == '__main__':    app.run(debug=True)

Then you just need a simple movies.html displaying the list of movies and providing a form to add a new one; and a single_movie.html presenting the informations of a movie and providing a form to update it as well as a delete button.


Viewing latest article 1
Browse Latest Browse All 3

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>