Finished Basic Migration to new Schema
This commit is contained in:
parent
ce8e63b596
commit
0cca96bb13
@ -29,26 +29,26 @@ def shopping_list(mode, id):
|
|||||||
|
|
||||||
|
|
||||||
# API CALLS
|
# API CALLS
|
||||||
|
# Added to Database
|
||||||
@shopping_list_api.route('/api/addList', methods=["POST"])
|
@shopping_list_api.route('/api/addList', methods=["POST"])
|
||||||
def addList():
|
def addList():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
list_name = request.get_json()['list_name']
|
list_name = request.get_json()['list_name']
|
||||||
list_description = request.get_json()['list_description']
|
list_description = request.get_json()['list_description']
|
||||||
list_type = request.get_json()['list_type']
|
list_type = request.get_json()['list_type']
|
||||||
database_config = config()
|
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
user_id = session['user_id']
|
user_id = session['user_id']
|
||||||
with psycopg2.connect(**database_config) as conn:
|
shopping_list = database_payloads.ShoppingListPayload(
|
||||||
shopping_list = MyDataclasses.ShoppingListPayload(
|
|
||||||
name=list_name,
|
name=list_name,
|
||||||
description=list_description,
|
description=list_description,
|
||||||
author=user_id,
|
author=user_id,
|
||||||
type=list_type
|
type=list_type
|
||||||
)
|
)
|
||||||
database.insertShoppingListsTuple(conn, site_name, shopping_list.payload())
|
shoplist_database.insertShoppingListsTuple(site_name, shopping_list.payload())
|
||||||
return jsonify({'error': False, 'message': 'List added!!'})
|
return jsonify({'error': False, 'message': 'List added!!'})
|
||||||
return jsonify({'error': True, 'message': 'These was an error with adding the list!'})
|
return jsonify({'error': True, 'message': 'These was an error with adding the list!'})
|
||||||
|
|
||||||
|
# Added to Database
|
||||||
@shopping_list_api.route('/api/getLists', methods=["GET"])
|
@shopping_list_api.route('/api/getLists', methods=["GET"])
|
||||||
def getShoppingLists():
|
def getShoppingLists():
|
||||||
lists = []
|
lists = []
|
||||||
@ -56,16 +56,15 @@ def getShoppingLists():
|
|||||||
page = int(request.args.get('page', 1))
|
page = int(request.args.get('page', 1))
|
||||||
limit = int(request.args.get('limit', 1))
|
limit = int(request.args.get('limit', 1))
|
||||||
offset = (page-1)*limit
|
offset = (page-1)*limit
|
||||||
database_config = config()
|
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
with psycopg2.connect(**database_config) as conn:
|
lists, count = shoplist_database.getShoppingLists(site_name, (limit, offset))
|
||||||
lists, count = database.getShoppingLists(conn, site_name, (limit, offset), convert=True)
|
|
||||||
|
|
||||||
for list in lists:
|
for list in lists:
|
||||||
|
|
||||||
if list['type'] == 'calculated':
|
if list['type'] == 'calculated':
|
||||||
items = []
|
items = []
|
||||||
not_items = database.getItemsSafetyStock(conn, site_name, convert=True)
|
not_items = shoplist_database.getItemsSafetyStock(site_name)
|
||||||
for item in not_items:
|
for item in not_items:
|
||||||
new_item = {
|
new_item = {
|
||||||
'id': item['id'],
|
'id': item['id'],
|
||||||
@ -83,15 +82,14 @@ def getShoppingLists():
|
|||||||
|
|
||||||
return jsonify({'shopping_lists': lists, 'end':math.ceil(count/limit), 'error': False, 'message': 'Lists queried successfully!'})
|
return jsonify({'shopping_lists': lists, 'end':math.ceil(count/limit), 'error': False, 'message': 'Lists queried successfully!'})
|
||||||
|
|
||||||
|
# Added to Database
|
||||||
@shopping_list_api.route('/api/getList', methods=["GET"])
|
@shopping_list_api.route('/api/getList', methods=["GET"])
|
||||||
def getShoppingList():
|
def getShoppingList():
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
sl_id = int(request.args.get('id', 1))
|
sl_id = int(request.args.get('id', 1))
|
||||||
database_config = config()
|
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
with psycopg2.connect(**database_config) as conn:
|
list = shoplist_database.getShoppingList(site_name, (sl_id, ))
|
||||||
lists = database.getShoppingList(conn, site_name, (sl_id, ), convert=True)
|
return jsonify({'shopping_list': list, 'error': False, 'message': 'Lists queried successfully!'})
|
||||||
return jsonify({'shopping_list': lists, 'error': False, 'message': 'Lists queried successfully!'})
|
|
||||||
|
|
||||||
# Added to Database
|
# Added to Database
|
||||||
@shopping_list_api.route('/api/getListItem', methods=["GET"])
|
@shopping_list_api.route('/api/getListItem', methods=["GET"])
|
||||||
@ -151,27 +149,26 @@ def deleteListItem():
|
|||||||
return jsonify({"error":False, "message":"item deleted succesfully!"})
|
return jsonify({"error":False, "message":"item deleted succesfully!"})
|
||||||
return jsonify({"error":True, "message":"There was an error with this POST statement"})
|
return jsonify({"error":True, "message":"There was an error with this POST statement"})
|
||||||
|
|
||||||
|
# Added to Database
|
||||||
@shopping_list_api.route('/api/saveListItem', methods=["POST"])
|
@shopping_list_api.route('/api/saveListItem', methods=["POST"])
|
||||||
def saveListItem():
|
def saveListItem():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
sli_id = request.get_json()['sli_id']
|
sli_id = request.get_json()['sli_id']
|
||||||
update = request.get_json()['update']
|
update = request.get_json()['update']
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
database_config = config()
|
shoplist_database.updateShoppingListItemsTuple(site_name, {'id': sli_id, 'update': update})
|
||||||
with psycopg2.connect(**database_config) as conn:
|
|
||||||
database.__updateTuple(conn, site_name, f"{site_name}_shopping_list_items", {'id': sli_id, 'update': update})
|
|
||||||
return jsonify({"error":False, "message":"items fetched succesfully!"})
|
return jsonify({"error":False, "message":"items fetched succesfully!"})
|
||||||
return jsonify({"error":True, "message":"There was an error with this GET statement"})
|
return jsonify({"error":True, "message":"There was an error with this GET statement"})
|
||||||
|
|
||||||
|
# Added to Database
|
||||||
@shopping_list_api.route('/api/getSKUItemsFull', methods=["GET"])
|
@shopping_list_api.route('/api/getSKUItemsFull', methods=["GET"])
|
||||||
def getSKUItemsFull():
|
def getSKUItemsFull():
|
||||||
items = []
|
items = []
|
||||||
count = {'count': 0}
|
count = {'count': 0}
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
site_name = session['selected_site']
|
site_name = session['selected_site']
|
||||||
database_config = config()
|
|
||||||
with psycopg2.connect(**database_config) as conn:
|
not_items = shoplist_database.getItemsSafetyStock(site_name)
|
||||||
not_items = database.getItemsSafetyStock(conn, site_name, convert=True)
|
|
||||||
for item in not_items:
|
for item in not_items:
|
||||||
new_item = {
|
new_item = {
|
||||||
'id': item['id'],
|
'id': item['id'],
|
||||||
|
|||||||
@ -4,21 +4,95 @@ import psycopg2
|
|||||||
import config
|
import config
|
||||||
from application import postsqldb
|
from application import postsqldb
|
||||||
|
|
||||||
|
def getShoppingList(site, payload, convert=True, conn=None):
|
||||||
|
recordset = []
|
||||||
|
self_conn = False
|
||||||
|
|
||||||
|
with open(f"application/shoppinglists/sql/getShoppingListByID.sql", "r+") as file:
|
||||||
|
sql = file.read().replace("%%site_name%%", site)
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, payload)
|
||||||
|
rows = cur.fetchone()
|
||||||
|
if rows and convert:
|
||||||
|
recordset = postsqldb.tupleDictionaryFactory(cur.description, rows)
|
||||||
|
if rows and not convert:
|
||||||
|
recordset = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return recordset
|
||||||
|
|
||||||
|
except (Exception, psycopg2.DatabaseError) as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def getShoppingLists(site, payload, convert=True, conn=None):
|
||||||
|
recordset = []
|
||||||
|
count = 0
|
||||||
|
self_conn = False
|
||||||
|
with open(f"application/shoppinglists/sql/getShoppingLists.sql", "r+") as file:
|
||||||
|
sql = file.read().replace("%%site_name%%", site)
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, payload)
|
||||||
|
rows = cur.fetchall()
|
||||||
|
if rows and convert:
|
||||||
|
recordset = [postsqldb.tupleDictionaryFactory(cur.description, row) for row in rows]
|
||||||
|
if rows and not convert:
|
||||||
|
recordset = rows
|
||||||
|
|
||||||
|
cur.execute(f"SELECT COUNT(*) FROM {site}_shopping_lists;")
|
||||||
|
count = cur.fetchone()[0]
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return recordset, count
|
||||||
|
except (Exception, psycopg2.DatabaseError) as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def getItemsSafetyStock(site, convert=True, conn=None):
|
||||||
|
recordsets = []
|
||||||
|
self_conn = False
|
||||||
|
with open(f"application/shoppinglists/sql/getItemsSafetyStock.sql", "r+") as file:
|
||||||
|
sql = file.read().replace("%%site_name%%", site)
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql)
|
||||||
|
rows = cur.fetchall()
|
||||||
|
if rows and convert:
|
||||||
|
recordsets = [postsqldb.tupleDictionaryFactory(cur.description, row) for row in rows]
|
||||||
|
if rows and not convert:
|
||||||
|
recordsets = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return recordsets
|
||||||
|
|
||||||
|
except (Exception, psycopg2.DatabaseError) as error:
|
||||||
|
raise postsqldb.DatabaseError(error, None, sql)
|
||||||
|
|
||||||
def getShoppingListItem(site, payload, convert=True, conn=None):
|
def getShoppingListItem(site, payload, convert=True, conn=None):
|
||||||
"""_summary_
|
|
||||||
|
|
||||||
Args:
|
|
||||||
conn (_type_): _description_
|
|
||||||
site (_type_): _description_
|
|
||||||
payload (_type_): (id, )
|
|
||||||
convert (bool, optional): _description_. Defaults to True.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
DatabaseError: _description_
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
_type_: _description_
|
|
||||||
"""
|
|
||||||
record = ()
|
record = ()
|
||||||
self_conn = False
|
self_conn = False
|
||||||
with open('application/shoppinglists/sql/selectShoppingListItem.sql', 'r') as file:
|
with open('application/shoppinglists/sql/selectShoppingListItem.sql', 'r') as file:
|
||||||
@ -46,7 +120,6 @@ def getShoppingListItem(site, payload, convert=True, conn=None):
|
|||||||
except Exception as error:
|
except Exception as error:
|
||||||
raise postsqldb.DatabaseError(error, payload, sql)
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
|
||||||
def getItemsWithQOH(site, payload, convert=True, conn=None):
|
def getItemsWithQOH(site, payload, convert=True, conn=None):
|
||||||
recordset = []
|
recordset = []
|
||||||
count = 0
|
count = 0
|
||||||
@ -115,6 +188,34 @@ def deleteShoppingListItemsTuple(site_name, payload, convert=True, conn=None):
|
|||||||
except Exception as error:
|
except Exception as error:
|
||||||
raise postsqldb.DatabaseError(error, payload, sql)
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def insertShoppingListsTuple(site, payload, convert=True, conn=None):
|
||||||
|
shopping_list = ()
|
||||||
|
self_conn = False
|
||||||
|
with open(f"application/shoppinglists/sql/insertShoppingListsTuple.sql", "r+") as file:
|
||||||
|
sql = file.read().replace("%%site_name%%", site)
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, payload)
|
||||||
|
rows = cur.fetchone()
|
||||||
|
if rows and convert:
|
||||||
|
shopping_list = postsqldb.tupleDictionaryFactory(cur.description, rows)
|
||||||
|
elif rows and not convert:
|
||||||
|
shopping_list = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return shopping_list
|
||||||
|
except Exception as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
def insertShoppingListItemsTuple(site, payload, convert=True, conn=None):
|
def insertShoppingListItemsTuple(site, payload, convert=True, conn=None):
|
||||||
shopping_list_item = ()
|
shopping_list_item = ()
|
||||||
self_conn = False
|
self_conn = False
|
||||||
@ -144,3 +245,32 @@ def insertShoppingListItemsTuple(site, payload, convert=True, conn=None):
|
|||||||
|
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
raise postsqldb.DatabaseError(error, payload, sql)
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
|
|
||||||
|
def updateShoppingListItemsTuple(site, payload, convert=True, conn=None):
|
||||||
|
updated = ()
|
||||||
|
self_conn = False
|
||||||
|
set_clause, values = postsqldb.updateStringFactory(payload['update'])
|
||||||
|
values.append(payload['id'])
|
||||||
|
sql = f"UPDATE {site}_shopping_list_items SET {set_clause} WHERE id=%s RETURNING *;"
|
||||||
|
try:
|
||||||
|
if not conn:
|
||||||
|
database_config = config.config()
|
||||||
|
conn = psycopg2.connect(**database_config)
|
||||||
|
conn.autocommit = True
|
||||||
|
self_conn = True
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(sql, values)
|
||||||
|
rows = cur.fetchone()
|
||||||
|
if rows and convert:
|
||||||
|
updated = postsqldb.tupleDictionaryFactory(cur.description, rows)
|
||||||
|
elif rows and not convert:
|
||||||
|
updated = rows
|
||||||
|
|
||||||
|
if self_conn:
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return updated
|
||||||
|
except Exception as error:
|
||||||
|
raise postsqldb.DatabaseError(error, payload, sql)
|
||||||
11
application/shoppinglists/sql/getItemsSafetyStock.sql
Normal file
11
application/shoppinglists/sql/getItemsSafetyStock.sql
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
WITH sum_cte AS (
|
||||||
|
SELECT mi.id, SUM(mil.quantity_on_hand) AS total_sum
|
||||||
|
FROM %%site_name%%_item_locations mil
|
||||||
|
JOIN %%site_name%%_items mi ON mil.part_id = mi.id
|
||||||
|
GROUP BY mi.id
|
||||||
|
)
|
||||||
|
SELECT *
|
||||||
|
FROM %%site_name%%_items
|
||||||
|
LEFT JOIN %%site_name%%_item_info ON %%site_name%%_items.item_info_id = %%site_name%%_item_info.id
|
||||||
|
LEFT JOIN sum_cte ON %%site_name%%_items.id = sum_cte.id
|
||||||
|
WHERE %%site_name%%_item_info.safety_stock > COALESCE(sum_cte.total_sum, 0);
|
||||||
15
application/shoppinglists/sql/getShoppingListByID.sql
Normal file
15
application/shoppinglists/sql/getShoppingListByID.sql
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
WITH passed_id AS (SELECT %s AS passed_id),
|
||||||
|
cte_sl_items AS (
|
||||||
|
SELECT items.*,
|
||||||
|
(SELECT COALESCE(row_to_json(un), '{}') FROM units un WHERE un.id = items.uom LIMIT 1) AS uom
|
||||||
|
FROM %%site_name%%_shopping_list_items items
|
||||||
|
WHERE items.sl_id = (SELECT passed_id FROM passed_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
SELECT (SELECT passed_id FROM passed_id) AS passed_id,
|
||||||
|
%%site_name%%_shopping_lists.*,
|
||||||
|
logins.username as author,
|
||||||
|
(SELECT COALESCE(array_agg(row_to_json(slis)), '{}') FROM cte_sl_items slis) AS sl_items
|
||||||
|
FROM %%site_name%%_shopping_lists
|
||||||
|
JOIN logins ON %%site_name%%_shopping_lists.author = logins.id
|
||||||
|
WHERE %%site_name%%_shopping_lists.id=(SELECT passed_id FROM passed_id)
|
||||||
3
application/shoppinglists/sql/getShoppingLists.sql
Normal file
3
application/shoppinglists/sql/getShoppingLists.sql
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SELECT *,
|
||||||
|
(SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM %%site_name%%_shopping_list_items g WHERE sl_id = %%site_name%%_shopping_lists.id) AS sl_items
|
||||||
|
FROM %%site_name%%_shopping_lists LIMIT %s OFFSET %s;
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
INSERT INTO %%site_name%%_shopping_lists
|
||||||
|
(name, description, author, creation_date, type)
|
||||||
|
VALUES (%s, %s, %s, %s, %s)
|
||||||
|
RETURNING *;
|
||||||
@ -158,7 +158,7 @@ async function openLineEditModal(sli_id) {
|
|||||||
console.log(sl_item)
|
console.log(sl_item)
|
||||||
document.getElementById('lineName').value = sl_item.item_name
|
document.getElementById('lineName').value = sl_item.item_name
|
||||||
document.getElementById('lineQty').value = sl_item.qty
|
document.getElementById('lineQty').value = sl_item.qty
|
||||||
document.getElementById('lineUOM').value = sl_item.uom.fullname
|
document.getElementById('lineUOM').value = sl_item.uom.id
|
||||||
console.log(sl_item.links)
|
console.log(sl_item.links)
|
||||||
|
|
||||||
if(!sl_item.links.hasOwnProperty('main')){
|
if(!sl_item.links.hasOwnProperty('main')){
|
||||||
|
|||||||
@ -60,7 +60,7 @@ async function replenishLineTable(sl_items){
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchShoppingList() {
|
async function fetchShoppingList() {
|
||||||
const url = new URL('/shopping-lists/getList', window.location.origin);
|
const url = new URL('/shopping-lists/api/getList', window.location.origin);
|
||||||
url.searchParams.append('id', sl_id);
|
url.searchParams.append('id', sl_id);
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
data = await response.json();
|
data = await response.json();
|
||||||
@ -68,7 +68,7 @@ async function fetchShoppingList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchSLItem(sli_id) {
|
async function fetchSLItem(sli_id) {
|
||||||
const url = new URL('/shopping-lists/getListItem', window.location.origin);
|
const url = new URL('/shopping-lists/api/getListItem', window.location.origin);
|
||||||
url.searchParams.append('sli_id', sli_id);
|
url.searchParams.append('sli_id', sli_id);
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
data = await response.json();
|
data = await response.json();
|
||||||
@ -76,7 +76,7 @@ async function fetchSLItem(sli_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchItemsFullCalculated() {
|
async function fetchItemsFullCalculated() {
|
||||||
const url = new URL('/shopping-lists/getSKUItemsFull', window.location.origin);
|
const url = new URL('/shopping-lists/api/getSKUItemsFull', window.location.origin);
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
data = await response.json();
|
data = await response.json();
|
||||||
return data.list_items;
|
return data.list_items;
|
||||||
|
|||||||
@ -1956,3 +1956,9 @@
|
|||||||
2025-07-12 08:43:43.017720 --- ERROR --- DatabaseError(message='invalid input syntax for type integer: " Pinch"LINE 1: ... = 'Acai-Blueberry-Pomegranate', qty = '1', uom = ' Pinch', ... ^',
|
2025-07-12 08:43:43.017720 --- ERROR --- DatabaseError(message='invalid input syntax for type integer: " Pinch"LINE 1: ... = 'Acai-Blueberry-Pomegranate', qty = '1', uom = ' Pinch', ... ^',
|
||||||
payload={'id': 12, 'update': {'item_name': 'Acai-Blueberry-Pomegranate', 'qty': '1', 'uom': ' Pinch', 'links': {'main': 'test'}}},
|
payload={'id': 12, 'update': {'item_name': 'Acai-Blueberry-Pomegranate', 'qty': '1', 'uom': ' Pinch', 'links': {'main': 'test'}}},
|
||||||
sql='UPDATE test_shopping_list_items SET item_name = %s, qty = %s, uom = %s, links = %s WHERE id=%s RETURNING *;')
|
sql='UPDATE test_shopping_list_items SET item_name = %s, qty = %s, uom = %s, links = %s WHERE id=%s RETURNING *;')
|
||||||
|
2025-07-12 09:06:37.431664 --- ERROR --- DatabaseError(message='invalid input syntax for type integer: "each"LINE 3: VALUES ('5vpg73z', '5', 'custom', 'test', 'each', 2, NULL, '... ^',
|
||||||
|
payload=('5vpg73z', '5', 'custom', 'test', 'each', 2, None, '{"main": "test"}'),
|
||||||
|
sql='INSERT INTO test_shopping_list_items(uuid, sl_id, item_type, item_name, uom, qty, item_id, links) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING *;')
|
||||||
|
2025-07-12 09:29:10.063362 --- ERROR --- DatabaseError(message='tuple index out of range',
|
||||||
|
payload=(5,),
|
||||||
|
sql='SELECT *, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM test_shopping_list_items g WHERE sl_id = test_shopping_lists.id) AS sl_items FROM test_shopping_lists LIMIT %s OFFSET %s;')
|
||||||
Loading…
x
Reference in New Issue
Block a user