remove use of sql direct for insert into, delete from AND fix bug with parent variable not being set before use - this bug must have been there a while untested AND push FLASK_ENV into config for container, development mode so we can show it better in navbar

This commit is contained in:
2023-07-02 12:57:49 +10:00
parent f4962e5fd8
commit 867924fa60

55
main.py
View File

@@ -1,5 +1,6 @@
from flask import Flask, render_template, request, redirect, jsonify, url_for
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import desc
from sqlalchemy.exc import SQLAlchemyError
from flask_marshmallow import Marshmallow
from flask_bootstrap import Bootstrap
@@ -23,9 +24,10 @@ if os.environ['FLASK_ENV'] == "production":
DB_URL = 'postgresql+psycopg2://ddp:blahdeblah@bookdb:5432/library'
app.config['FLASK_ENV']="production"
elif os.environ['FLASK_ENV'] == "container":
app.config['FLASK_ENV']="dev"
app.config['FLASK_ENV']="container"
DB_URL = 'postgresql+psycopg2://ddp:blahdeblah@bookdb_dev:5432/library'
else:
app.config['FLASK_ENV']="development"
DB_URL = 'postgresql+psycopg2://ddp:blahdeblah@127.0.0.1:55432/library'
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URL
@@ -593,7 +595,7 @@ def new_book():
book=Book.query.get(request.form['add_sub_parent_id'])
bb=QuickParentBook()
bb.parent=[]
bb.parent.append( { 'id': parent, 'title': book.title } )
bb.parent.append( { 'id': book.id, 'title': book.title } )
form.publisher.default = book.publisher
form.owned.default = book.owned
form.condition.default = book.condition
@@ -616,23 +618,33 @@ def new_book():
# this is a sub-book we have added (after the data has been entered, now we commit it to DB)
if 'parent_id' in request.form:
with db.engine.connect() as conn:
conn.exec_driver_sql( "insert into book_sub_book_link ( book_id, sub_book_id, sub_book_num ) values ( {}, {}, (select COALESCE(MAX(sub_book_num),0)+1 from book_sub_book_link where book_id = {}) )".format( request.form['parent_id'], book.id, request.form['parent_id'] ) )
parent=Book.query.get(request.form['parent_id'])
max_bsbl = Book_Sub_Book_Link.query.filter(Book_Sub_Book_Link.book_id==parent.id).order_by(desc(Book_Sub_Book_Link.sub_book_num)).first()
print( f"max_bsbl={max_bsbl}" )
max_sbn=max_bsbl.sub_book_num
if max_sbn == None:
max_sbn=0
new_bsbl = Book_Sub_Book_Link( book_id=parent.id, sub_book_id=book.id, sub_book_num=max_sbn+1 )
db.session.add(new_bsbl)
if len(parent.series) > 0:
# we have added a sub-book to something in a series already, so add a bsl for the next book_num
for s in parent.bsl:
with db.engine.connect() as conn:
conn.exec_driver_sql( "insert into book_series_link ( series_id, book_id, book_num ) values ( {}, {}, (select COALESCE(MAX(book_num),0)+1 from book_series_link where series_id={}) )".format( s.series_id, book.id, s.series_id ) )
# decided to do this as I could not see how to use Book_Series_Link.query with func.max, and I wanted to use ORM
max_bsl = Book_Series_Link.query.filter(Book_Series_Link.series_id==s.series_id,Book_Series_Link.book_num!=None).order_by(desc(Book_Series_Link.book_num)).first()
max_bn=max_bsl.book_num
if max_bn == None:
max_bn=0
newbsl=Book_Series_Link( book_id=book.id, series_id=s.series_id, book_num=max_bn+1 )
db.session.add(newbsl)
db.session.commit()
st.SetMessage( "Created new Book ({})".format(book.title) )
cnt=1
for field in request.form:
if 'bsl-book_id-' in field and field != 'bsl-book_id-NUM':
cnt=int(re.findall( '\d+', field )[0])
sql="insert into book_series_link (book_id, series_id, book_num) values ( {}, {}, {} )".format( book.id, request.form['bsl-series_id-{}'.format(cnt)], request.form['bsl-book_num-{}'.format(cnt)])
with db.engine.connect() as conn:
conn.exec_driver_sql( sql )
newbsl=Book_Series_Link( book_id=book.id, series_id=request.form[ f"bsl-series_id-{cnt}"], book_num=request.form[ f"bsl-book_num-{cnt}"] )
db.session.add(newbsl)
db.session.commit()
cnt=cnt+1
return redirect( '/book/{}'.format(book.id) )
else:
@@ -786,7 +798,6 @@ def book(id):
for field in request.form:
if 'bsl-book_id-' in field and field != 'bsl-book_id-NUM':
cnt=int(re.findall( '\d+', field )[0])
print( f"here: field={field}, cnt={cnt}" )
if book.IsParent():
newbsl=Book_Series_Link( book_id=request.form[f'bsl-book_id-{cnt}'],
series_id=request.form[f'bsl-series_id-{cnt}'] )
@@ -796,7 +807,6 @@ def book(id):
book_num=request.form[f'bsl-book_num-{cnt}'] )
# add the contains (null for book_num) bsl for the parent book
if book.IsChild():
print( f"FINAL: pid={book.parent[0].id}, sid={request.form[f'bsl-series_id-{cnt}']}" )
parent_bsl=Book_Series_Link( book_id=book.parent[0].id, series_id=request.form[f'bsl-series_id-{cnt}'] )
db.session.add(parent_bsl)
db.session.add(newbsl)
@@ -894,26 +904,18 @@ def add_books_to_loan(id):
@app.route("/rem_parent_books_from_series/<pid>", methods=["POST"])
@login_required
def rem_parent_books_from_series(pid):
print ("pid={}".format(pid) )
try:
with db.engine.connect() as conn:
conn.exec_driver_sql( "delete from book_series_link where book_id in ( select sub_book_id from book_sub_book_link where book_id = {} ) ".format( pid ))
conn.exec_driver_sql( "delete from book_series_link where book_id = {}".format( pid ))
db.session.commit()
except SQLAlchemyError as e:
st.SetAlert("danger")
st.SetMessage("Failed to delete parent & sub books from ALL series! -- {}".format( e.orig ))
parent=Book.query.get(pid)
for sb in parent.child_ref:
Book_Series_Link.query.filter(Book_Series_Link.book_id==sb.sub_book_id).delete()
Book_Series_Link.query.filter(Book_Series_Link.book_id==pid).delete()
db.session.commit()
return jsonify(success=True)
@app.route("/books_on_shelf", methods=["GET"])
@login_required
def books_on_shelf():
# start with basic sort by title (we will sort by author at the end) in javascript,
# also re-order this list to deal with series ordering - this will leave overall sort by
# author, title & the moment we hit a series, the rest of those books are ordered by series
# start with all books owned by title, but it includes sub-books, so remove them...
# books = Book.query.join(Owned).filter(Owned.name=='Currently Owned').order_by(Book.title).all()
# start with all books owned sorted by author, then title, but it includes sub-books, so remove them...
books = Book.query.join(Owned).join(Book_Author_Link).join(Author).filter(Owned.name=='Currently Owned').filter(Book_Author_Link.author_num==1).order_by(Author.surname,Author.firstnames,Book.title).all()
RemSubs(books)
@@ -955,9 +957,6 @@ def books_on_shelf():
# book not in a series or a sub-book, so just add this book to the ordered list
ordered_books.append(b)
# return render_template("books.html", books=ordered_books, page_title="Books on Shelf", order_by="Author(s)", show_cols='', hide_cols='' )
for o in ordered_books:
print( f"ord: {o.title}" )
return render_template("books.html", books=ordered_books, page_title="Books on Shelf", order_by="", show_cols='', hide_cols='' )
@app.route("/unrated_books", methods=["GET"])