Tkinter SQLite Query Window using Toplevel and SQLAlchemy

Tkinter Toplevel query window for SQLite connector

This project extends the Tkinter SQLite connector from Part 1. After connecting to an SQLite database, the user can open a child window using Toplevel, enter an SQL statement and display the result in the main Tkinter window.

Queries that return records are displayed in a Treeview. Statements such as INSERT, UPDATE, DELETE or CREATE are committed and the number of affected rows is reported when available.

SQLite database
      |
      v
connection.py
      |
      v
Main Tkinter window
      |
      +--> table list
      |
      +--> Query button
              |
              v
          Toplevel
              |
              v
          SQL Text
              |
              v
       SQLAlchemy text()
              |
              v
       result.returns_rows
         /           \
       yes            no
        |              |
     Treeview       commit
                     |
                 rows affected
Database changes: this is a local SQL query tool. INSERT, UPDATE, DELETE, CREATE, DROP and other non-read-only statements can modify the selected database. The application asks for confirmation before executing them.

Use the SQLite Connection from Part 1 Top ↑

The database browser and connection logic remain in the connection.py file created in Connector Part 1.

The application imports:

from connection import my_connect

and receives:

new_conn,output,file_path=my_connect(
    status
)

The existing Part 1 interface is therefore retained:

my_connect('existing')
my_connect('new')

Display SQLite Table Names Top ↑

After connecting, query SQLite's schema table:

table_sql=text(
    "SELECT name FROM sqlite_master "
    "WHERE type='table' "
    "AND name NOT LIKE 'sqlite_%' "
    "ORDER BY name"
)

result=my_conn.execute(
    table_sql
)

The returned table names are displayed in a Listbox.

Double-clicking a table prepares a query such as:

SELECT * FROM "student" LIMIT 100

The table name comes from SQLite's schema listing rather than free-form user input.

Open the Toplevel Query Window Top ↑

The Query button creates a child window:

query_window=tk.Toplevel(
    root
)

query_window.title(
    'SQLite Query - plus2net'
)

A multiline Text widget is used because SQL statements can contain several lines.

editor=tk.Text(
    query_window,
    width=75,
    height=12,
    wrap='none'
)

Keep the SQL Available for Editing Top ↑

The older version destroyed the child window immediately after Submit. The revised query editor remains open so the same SQL can be modified and executed again.

The current SQL is also stored in a StringVar:

sql_str.set(
    query
)
write query
    |
    v
Run
    |
    v
inspect result
    |
    v
edit query
    |
    v
Run again

Ctrl+Enter also executes the SQL from the query editor.

Execute SQL using SQLAlchemy text() Top ↑

The older code passed SQL directly:

my_conn.execute(query)

The revised version creates an executable SQLAlchemy text statement:

statement=text(
    query
)

result=my_conn.execute(
    statement
)
Because this page is an SQL editor, the user deliberately enters the complete SQL statement. In normal application forms, values collected through Entry, Combobox and other widgets should be passed as SQL parameters rather than concatenated into SQL text.

Use result.returns_rows instead of Searching for SELECT Top ↑

The previous application used:

if query.lower().find(
    'select'
)!=-1:
    ...

This is unreliable. SQLAlchemy already reports whether the executed statement returned records:

if result.returns_rows:
    columns=list(
        result.keys()
    )

    rows=result.fetchmany(
        MAX_DISPLAY_ROWS+1
    )

Display Query Results in Treeview Top ↑

Column names are taken directly from the SQL result:

columns=list(
    result.keys()
)

Safe internal Treeview identifiers are generated:

column_ids=[
    f'c{i}'
    for i in range(
        len(columns)
    )
]

The actual database column names remain visible as Treeview headings.

Previous result rows are removed before showing another query:

tree.delete(
    *tree.get_children()
)

Display BLOB Values Safely Top ↑

Binary database values are displayed using their byte length instead of dumping the complete BLOB into Treeview.

<2048 bytes>

Commit INSERT, UPDATE and DELETE Statements Top ↑

Database-changing statements are committed explicitly:

my_conn.commit()

When rowcount is available, the interface can display:

Rows affected: 3

After schema changes, the table Listbox is refreshed so newly created or removed tables appear immediately.

Rollback after SQL Errors Top ↑

Execution is protected with exception handling.

except SQLAlchemyError as e:
    if my_conn.in_transaction():
        my_conn.rollback()

    original=getattr(
        e,
        'orig',
        e
    )

This avoids depending on an internal expression such as:

e.__dict__['orig']

Limit Large SQL Results in the GUI Top ↑

A query can return a very large number of rows. The GUI therefore uses:

MAX_DISPLAY_ROWS=500

and fetches one additional record:

rows=result.fetchmany(
    MAX_DISPLAY_ROWS+1
)

If more than 500 rows are available, the interface displays the first 500 and reports that the result has been limited.

Complete Tkinter SQLite Connector Part 2 Top ↑

This code continues to use the connection.py file from Part 1. It assumes my_connect(status) returns the SQLAlchemy Connection, status text and database path used by the existing connector project.

Example SQL Statements Top ↑

Display Records Top ↑

SELECT * FROM student LIMIT 20

Filter Records Top ↑

SELECT name,class,mark
FROM student
WHERE mark >= 80
ORDER BY mark DESC

Update a Record Top ↑

UPDATE student
SET mark=90
WHERE id=1

The application asks for confirmation before executing the UPDATE and commits the transaction after successful execution.

Create a Table Top ↑

CREATE TABLE test_table(
    id INTEGER PRIMARY KEY,
    name TEXT
)

After successful execution, the table Listbox is refreshed automatically.

Why result.returns_rows Is Better Top ↑

The old program tried to determine the SQL result type by searching the query text:

Does query contain "select"?

The revised application asks SQLAlchemy about the executed result:

result.returns_rows
Execute SQL
     |
     v
SQLAlchemy Result
     |
     v
result.returns_rows
   /          \
 True         False
  |             |
show rows      commit
in Treeview    changes

Video: Tkinter Child Query Window for SQLite Top ↑

Tkinter child window using Toplevel to execute user entered SQL query on SQLite and display result

Continue the SQLite Connector Project Top ↑

Start with database selection and connection:

SQLite Connector Part 1

Continue with the next SQL connector section:

SQLite Connector Part 3

For a Pandas-based SQLite viewer with sorting and CSV export:

SQLite DataFrame Viewer

Frequently Asked Questions Top ↑

Q1: How do I open a child query window in Tkinter?

Use tk.Toplevel(). The child window can contain a Text widget for entering SQL and Buttons for running or clearing the statement.

Q2: Why use SQLAlchemy text() when executing SQL?

text() converts the SQL string into an executable SQLAlchemy text statement for the current execution API.

Q3: How do I know whether an SQL statement returned rows?

Check result.returns_rows. When it is true, result column names and records can be read and displayed.

Q4: Why does the application commit UPDATE and INSERT statements?

Database-changing statements must be committed so their changes remain in the SQLite database.

Q5: What happens when an SQL statement fails?

The application rolls back the active transaction and displays the database error in the status area.

Q6: Why are only 500 result rows displayed?

Limiting Treeview output prevents very large SQL results from creating thousands of GUI rows and making the interface difficult to use.

Q7: Does the query window remember the previous SQL?

Yes. The current SQL remains in the editor and is also stored in a StringVar so it can be edited and executed again.


Connector Part 1 Connector Part 3

Tkinter Projects


Subscribe to our YouTube Channel here



plus2net.com







Python Video Tutorials
Python SQLite Video Tutorials
Python MySQL Video Tutorials
Python Tkinter Video Tutorials
We use cookies to improve your browsing experience. . Learn more
HTML MySQL PHP JavaScript ASP Photoshop Articles Contact us
©2000-2026   plus2net.com   All rights reserved worldwide Privacy Policy Disclaimer