Put a Python Boundary Around the Database · practice
Read Result Columns by Name
The first available row currently appears as a positional
(1, 'IT-100', 'Cordless drill', 'tools', 7)
You know that 1 is the asset tag only because you can see the SELECT row[1] quietly depends on that order. This version says what it means:
row["asset_tag"]
row["name"]
SQLite can provide that named access with sqlite3.Row. The setting belongs to the connection and must be in place before the query executes:
connection.row_factory = sqlite3.Row
result = connection.execute("""complete query here""")
Open catalog_db.py. Keep the available-items SQL, result, fetchall(), and the temporary (result, rows) return exactly as they are. Add the row-factory result = connection.execute(...).
The two result is still a Cursor. Each rows is now a Row. A Row is not a row = rows[0], all of these refer to values produced by the query:
row["id"]
row["asset_tag"]
row["name"]
row["category"]
row["loan_days"]
Press Run. It makes the same call as before: list_available_items(connection). The outer return remains a tuple, the result type remains Cursor, and the row count remains four. The changed line is concrete:
First row type: Row
First row values: 1 | IT-100 | Cordless drill | tools | 7
The order of those printed values still comes from the exact query, while your Python code can now use their names. That makes a later change to the selected-column order much less likely to give a caller the wrong value silently.
Submit supplies a default connection, so the rows[0]. Keep the connection open. You will move this setting to the one place where connections are opened next.
Task
Update list_available_items(connection) so it sets connection.row_factory = sqlite3.Row before calling execute().
Keep the query and the temporary (result, rows) return unchanged. The returned sqlite3.Row values that support all five selected column names, and the supplied connection must remain open.