[Tutor] How to test for the existence of a table in a sqlite3 db?

boB Stepp robertvstepp at gmail.com
Sun Oct 15 11:09:09 EDT 2017

On Sun, Oct 15, 2017 at 3:09 AM, Peter Otten <__peter__ at web.de> wrote:
> boB Stepp wrote:
>> I have not used a "finally" block before.  I just had the thought that
>> maybe it would run even if an uncaught exception might occur.  I tried
>> to test this thought by generating a deliberate NameError in the "try"
>> block and added a print to the "finally" clause.  I got the intended
>> NameError with no evidence of the added print printing.  But I thought
>> I would ask just to be sure:  If an uncaught exception occurs, will
>> the "finally" clause execute?
> Yes.
>>>> try:
> ...     1/0
> ... except ValueError:
> ...     print("not triggered")
> ... finally:
> ...     print("ALWAYS TRIGGERED")
> ...
> Traceback (most recent call last):
>   File "<stdin>", line 2, in <module>
> ZeroDivisionError: division by zero

That is what I thought after reading about "finally".  But look what
happens if I modify my actual code to generate a NameError:

def ensure_db(filename):
    """Open the database, "filename", if it exists; otherwise, create a
    database named "filename"."""

    db = sqlite3.connect(filename)
    cur = db.cursor()

        sql_cmd = "SELECT VersionNumber FROM CurrentDBVersion"
        a    # This should generate a NameError
        # First element of returned tuple will be the db version number:
        current_db_version = int(cur.execute(sql_cmd).fetchone()[0])

    except sqlite3.OperationalError:
        # This means that the database and the table, "CurrentDBVersion", has
        # not yet been created, implying "version 0".
        current_db_version = 0

        sql_scripts = ["../database/create_sqlite3_db.sql"]
        for sql_scriptname in sql_scripts[current_db_version:]:
            with open(sql_scriptname) as f:
        print("THIS IS THE FINALLY BLOCK!!!")  # And this *should* print

    return db

This results in the following Traceback:

> py main.py
Traceback (most recent call last):
  File "main.py", line 16, in ensure_db
NameError: name 'a' is not defined

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 36, in <module>
  File "main.py", line 27, in ensure_db
    for sql_scriptname in sql_scripts[current_db_version:]:
UnboundLocalError: local variable 'current_db_version' referenced
before assignment

So what is going on here?  Why does "finally" not have its print
executed?  Does the "...another exception occurred:..." interrupt the
normal flow of the "try/except/finally" structure and prevent the
"finally" block from executing?


More information about the Tutor mailing list