cleaning up, schema.sql, init_db.py, new library.db

master
grgr 2 years ago
parent 12d915c476
commit 91d74b8b0e

@ -0,0 +1,70 @@
-------------------
TODO:
- ⭐ create flask app
- ⭐ create symple db with readings
- ⭐ add the form input to db
- ⭐ fetch all rows
- ⭐ getallrows returns a list to be iterated with jinja
- ⭐ and visualize them in the homepage (<table></table>)
- ⭐ fetch all tables function
- current date when posting in new item
- create new tables
- show all tables
- edit items
- remove item/entry from a table
- create tag system (type, topics, notes)
- sort notes (what if notes had their own tag system that interacts with the one of the resources?)
same goes for authors,create a table of authors that then can relate to biografies and connections for the topics they treat or for their personal connections... too much?
----- Notes ----- #
I wanted to create a reading list for the summer, in which I could add my comments and organize the readings through some personal categories. As I was also interested in relational tables and databases I started to do some tutorials with sqlite. This is the first attempt to apply those tutorials to the library, it's gonna be very basic initially, but I'll try to document the steps on the way. At the moment I have a vague idea of how the project can be developed but I'm really not aware of all the steps for sure.
So this is the process: I write initially a raw todo list with main steps I want to reach (like using flask, creating database etc), then I try to figure out the steps in-between to accomplish a main step. It ain't easy though.
I got stuck immediately when I tried to create the Flask application: I needed to register the prefix middleware to be able to see the front-end on the right port and url (asked to kamo and then copy pasted the lines about the prefix middleware from another project on the soupboat)
I created the first table of the database by running the create_table() funct in the add() url, which was a pretty ugly procedure, but then I could write a simpler function to add_book() that refers directly to that table (not so abstracted in this case, but will fix this part later on)
getAllRow() is also related to specific table of a db, so need to make it more abstract/general
In the beginning I wasn't sure that getAllRows() should return something, but as I understood I need to display the rows with jinja and html I got that I need a list of objects (in this case the rows of the db with books) to be able to populate the html table with my data
ok, it took me a while to understand how to pass the list of dictionaries (the reading list that i got from the funct getAllRows()) to the frontend. but it was because I didn't want to recreate the object of the row again, is there a quicker way to pass the list with all the arguments of its dictionaries?
yes there was a muh quiker way, just return the function getAllRows directly with the name of the db, it will pass directly the reding list to jinja
Right now I have something that looks like a very raw table. I'm thinking what's the next step. I'd like to create a system of tags but also a system of notation for each book. I'll do some research on notation and tag systems and a tutorial on relational tables
didn't do anything for days hahah I don't remember clearly what i was doing so documentation really helps me getting back on track
15/09/22
It's been a month that I haven't touched this proj. really difficult to pick up on what i did, because there is not a clear method in the documentation either. so now I will try to write the process only here and to reference the (current) lines of things
24/09/22
I've created a repo on git to be able to work on vsc and I used a virtual environment to develop the flask application. I did it by typing the command $ python -m venv folder_name
I have a question: can I use flask without venv?
Actually yes, even if at first I thought it wasn't possible, just because I blindly trusted people on Stack overflow, or by following the process on flask tutorials I got to set up this virtaulenv. The difference without the virtual env is that all the dependencies that I need would be installed globally on my computer and it might be unconvenient when a version of them will change or if I have a lot of stuff to download. So it turned out that creatinf a virtualenv could be a good practice.
VIRTUAL ENVIRONMENT:
"The virtual environment is basically a room open for your specific coding project. Instead of using os-wide defined Python or Python packages, it aims to isolate your Python and its dependent packages from all projects that are hosted by your computer."
https://medium.com/@pinareceaktan/what-is-this-virtual-environments-in-python-and-why-anyone-ever-needs-them-7e3e682f9d2
"No, there is no requirement to use a virtualenv. No project ever would require you to use one; it is just a method of insulating a collection of Python libraries from other projects.
I personally do strongly recommend you use a virtualenv, because it makes it much, much easier to swap out versions of libraries and not affect other Python projects."
https://stackoverflow.com/questions/32756711/is-it-necessary-to-use-virtualenv-to-use-flask-framework
27/06/22
I'm not sure how to continue at this point so I decided to check some tutorials and go through the steps they make, to understand some other good practices for databases.
https://www.digitalocean.com/community/tutorials/how-to-use-one-to-many-database-relationships-with-flask-and-sqlite
https://www.digitalocean.com/community/tutorials/how-to-modify-items-in-a-one-to-many-database-relationships-with-flask-and-sqlite
https://www.digitalocean.com/community/tutorials/how-to-use-many-to-many-database-relationships-with-flask-and-sqlite
28/09/22
ok, after a few tutorials I realized there are other ways of building this relational database with reading lists and notes and references, so I'm gonna move this log on a md file, and re do everything from scratch since it doesn't make sense as it is now. or maybe should I publish this log on the console log of the client?
It is handier if the code is distributed in more files, with a dedicated schema.sql file and an init_db.py file where i can hadle the construction of the database
this way of working reminds me of a tapestry, with threads being pulled from both the front and the back of the weaving frame

@ -0,0 +1,15 @@
import sqlite3
# create a connection to the database following the structure of schema.sql
connection = sqlite3.connect('library.db')
with open('schema.sql') as f:
connection.executescript(f.read())
cur = connection.cursor()
# close conenction
connection.commit()
connection.close()

Binary file not shown.

@ -1,6 +1,6 @@
# THE LIBRARY # # THE LIBRARY #
# from crypt import methods from itertools import groupby # to handle complex iterations
import os import os
import sqlite3 import sqlite3
@ -9,100 +9,6 @@ from flask import Flask, render_template, url_for, request, redirect
# ----- functions ----- # # ----- functions ----- #
# create table
def createNewTable(tab_name):
''' input types str, and list of strings'''
try:
connection = sqlite3.connect('library.db')
cursor = connection.cursor()
print(f'connected to library.db')
table = f'''CREATE TABLE {tab_name}
(topic)
'''
cursor.execute(table)
print(f'table {tab_name} created successfully')
cursor.close()
except sqlite3.Error as error:
print("Failed to create a new table", error)
finally:
if connection:
connection.close()
print("The Sqlite connection is closed")
def getAllTables(db_name):
'''input type str, returns a list'''
tables = []
try:
connection = sqlite3.connect(db_name)
cursor = connection.cursor()
print("connected to" + db_name)
sql_query = """SELECT name FROM sqlite_master
WHERE type='table';"""
cursor.execute(sql_query)
print("list of tables:")
tables_available = cursor.fetchall()
for table in tables_available:
print(table)
except sqlite3.Error as error:
print("Failed to execute the above query", error)
finally:
if connection:
connection.close()
print("the sqlite connection is closed")
return tables
# probably need to make this more general and put add book inside the routes' functions
# add entry for the table "reading list"
def add_book(author_n, book_title, text):
db = sqlite3.connect('library.db')
cursor = db.cursor()
cursor.execute("INSERT INTO reading_list VALUES (?,?,?)",
(author_n, book_title, text))
db.commit()
print(f"added {book_title} to the reading_list db")
db.close()
def getAllRows(db):
'''input type string, get all the rows of a db'''
rows_list = []
try:
connection = sqlite3.connect(db)
cursor = connection.cursor()
print("Connected to reading_list")
sqlite_select_query = """SELECT * from reading_list"""
cursor.execute(sqlite_select_query)
records = cursor.fetchall()
print("Total rows are: ", len(records))
print("Printing each row")
print("\n")
# f.e. the following is very specific of the library.db
for row in records:
row = {"author": row[0],
"title": row[1],
"description": row[2]}
rows_list.append(row)
print(row)
cursor.close()
except sqlite3.Error as error:
print("Failed to read data from table", error)
finally:
if connection:
connection.close()
print("The Sqlite connection is closed")
return rows_list
# ----- FLASK ----- # # ----- FLASK ----- #
@ -130,9 +36,8 @@ app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/soupboat/library')
@app.route("/", methods=['GET', 'POST']) @app.route("/", methods=['GET', 'POST'])
# @app.route("/")
def home(): def home():
getAllTables('./library.db')
if request.method == 'POST': if request.method == 'POST':
title = request.form.get('title') title = request.form.get('title')
@ -143,15 +48,7 @@ def home():
return render_template('home.html', reading_list=getAllRows('library.db')) return render_template('home.html', reading_list=getAllRows('library.db'))
# def reading_list():
# rows = getAllRows('library.db') #it's type list, you can try to print it
# reading_list = []
# for entry in rows:
# entry = {"author": entry["author"],
# "title": entry["title"],
# "description": entry["description"]}
# reading_list.append(entry)
# return reading_list
@app.route("/add", methods=['GET', 'POST']) @app.route("/add", methods=['GET', 'POST'])
@ -169,86 +66,9 @@ def add_new_page():
return redirect(url_for('home')) return redirect(url_for('home'))
return render_template('add_new.html') return render_template('add_new.html')
# so instead of having a function for everything there will be a unique function to create the category with relative table (it will probably be an augmented "create_table()" function
# def add_new_book():
# if request.method == 'POST':
# title = request.form.get('title')
# author = request.form.get('author')
# description = request.form.get('description')
# add_book(author, title, description)
# # if author:
# # return url_for('add_new_author')
# add_new_author()
# return redirect(url_for('home'))
# return render_template('add_book.html')
# the list of books doesn't have to coincide with the list of authors, but when you add a new book that has a new author the function will automacally add a new author so. shall it be in the home page?? (no mettiamo tutto nell'add new page con una funzione che aggiunge ogni elemento del form nella tabella corrispondente, se non esiste, aggiunge una nuova categoria)
app.run(port=3148) app.run(port=3148)
# -------------------
# TODO:
#
# - ⭐ create flask app
# - ⭐ create symple db with readings
# - ⭐ add the form input to db
# - ⭐ fetch all rows
# - ⭐ getallrows returns a list to be iterated with jinja
# - ⭐ and visualize them in the homepage (<table></table>)
# - ⭐ fetch all tables function
# - current date when posting in new item
# - create new tables
# - show all tables
# - edit items
# - remove item/entry from a table
# - create tag system (type, topics, notes)
# - sort notes (what if notes had their own tag system that interacts with the one of the resources?)
# same goes for authors,create a table of authors that then can relate to biografies and connections for the topics they treat or for their personal connections... too much?
# ----- Notes ----- #
# I wanted to create a reading list for the summer, in which I could add my comments and organize the readings through some personal categories. As I was also interested in relational tables and databases I started to do some tutorials with sqlite. This is the first attempt to apply those tutorials to the library, it's gonna be very basic initially, but I'll try to document the steps on the way. At the moment I have a vague idea of how the project can be developed but I'm really not aware of all the steps for sure.
# So this is the process: I write initially a raw todo list with main steps I want to reach (like using flask, creating database etc), then I try to figure out the steps in-between to accomplish a main step. It ain't easy though.
# I got stuck immediately when I tried to create the Flask application: I needed to register the prefix middleware to be able to see the front-end on the right port and url (asked to kamo and then copy pasted the lines about the prefix middleware from another project on the soupboat)
# I created the first table of the database by running the create_table() funct in the add() url, which was a pretty ugly procedure, but then I could write a simpler function to add_book() that refers directly to that table (not so abstracted in this case, but will fix this part later on)
# getAllRow() is also related to specific table of a db, so need to make it more abstract/general # TODO:
# - list the cards
# In the beginning I wasn't sure that getAllRows() should return something, but as I understood I need to display the rows with jinja and html I got that I need a list of objects (in this case the rows of the db with books) to be able to populate the html table with my data # - put its category inside
# ok, it took me a while to understand how to pass the list of dictionaries (the reading list that i got from the funct getAllRows()) to the frontend. but it was because I didn't want to recreate the object of the row again, is there a quicker way to pass the list with all the arguments of its dictionaries?
# yes there was a muh quiker way, just return the function getAllRows directly with the name of the db, it will pass directly the reding list to jinja
# Right now I have something that looks like a very raw table. I'm thinking what's the next step. I'd like to create a system of tags but also a system of notation for each book. I'll do some research on notation and tag systems and a tutorial on relational tables
# didn't do anything for days hahah I don't remember clearly what i was doing so documentation really helps me getting back on track
# 15/09/22
# It's been a month that I haven't touched this proj. really difficult to pick up on what i did, because there is not a clear method in the documentation either. so now I will try to write the process only here and to reference the (current) lines of things
# 24/09/22
# I've created a repo on git to be able to work on vsc and I used a virtual environment to develop the flask application. I did it by typing the command $ python -m venv folder_name
# I have a question: can I use flask without venv?
# Actually yes, even if at first I thought it wasn't possible, just because I blindly trusted people on Stack overflow, or by following the process on flask tutorials I got to set up this virtaulenv. The difference without the virtual env is that all the dependencies that I need would be installed globally on my computer and it might be unconvenient when a version of them will change or if I have a lot of stuff to download. So it turned out that creatinf a virtualenv could be a good practice.
# VIRTUAL ENVIRONMENT:
# "The virtual environment is basically a room open for your specific coding project. Instead of using os-wide defined Python or Python packages, it aims to isolate your Python and its dependent packages from all projects that are hosted by your computer."
# https://medium.com/@pinareceaktan/what-is-this-virtual-environments-in-python-and-why-anyone-ever-needs-them-7e3e682f9d2
# "No, there is no requirement to use a virtualenv. No project ever would require you to use one; it is just a method of insulating a collection of Python libraries from other projects.
# I personally do strongly recommend you use a virtualenv, because it makes it much, much easier to swap out versions of libraries and not affect other Python projects."
# https://stackoverflow.com/questions/32756711/is-it-necessary-to-use-virtualenv-to-use-flask-framework
# 27/06/22
# I'm not sure how to continue at this point so I decided to check some tutorials and go through the steps they make, to understand some other good practices for databases.
# https://www.digitalocean.com/community/tutorials/how-to-use-one-to-many-database-relationships-with-flask-and-sqlite
# https://www.digitalocean.com/community/tutorials/how-to-modify-items-in-a-one-to-many-database-relationships-with-flask-and-sqlite
# https://www.digitalocean.com/community/tutorials/how-to-use-many-to-many-database-relationships-with-flask-and-sqlite

@ -0,0 +1,18 @@
DROP TABLE IF EXISTS categories; -- is a list of categories(lists): type: reading_list, authors, notes, etc it's a type but type is also a keyword in python so better avoiding it
DROP TABLE IF EXISTS cards; --the single entry of any category/type
-- table creation
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL
);
CREATE TABLE cards (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category_id INTEGER NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
content TEXT NOT NULL,
FOREIGN KEY (category_id) REFERENCES categories (id)
);
Loading…
Cancel
Save