Sqlite — не может работать с закрытой базой данных

#python #sqlite #connection

#python #sqlite #подключение

Вопрос:

Я пытаюсь вставить небольшой набор строк в sqlite с помощью python и получаю сообщение об ошибке «Невозможно работать с закрытой базой данных»

Это мой фрагмент кода:

 import sqlite3
from sqlite3 import Error

db_file = "/home/sosuser/mediaserver/camera.db"

def create_connection(db_file):
    conn = None
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
    except Error as e:
        print(e)
    finally:
        if conn:
            conn.close()
    return conn

def create_task(conn, task):
    sql = ''' INSERT INTO camerainfo(id, cameraid, maplat, maplong, name)
              VALUES(?,?,?,?,?) '''
          
    cur = conn.cursor()
    cur.execute(sql, task)

def prepare_data(conn):
    for cam in range(len(camID)):
        print(camID[cam])
        task = (cam, camID[cam], '12.972442','77.580643','testCAM')
        create_task(conn, task)

    conn.commit()
    conn.close()

conn = create_connection(db_file)
prepare_data(conn)
  

Выдает следующую ошибку —

 Traceback (most recent call last):
  File "dumpCamera1.py", line 92, in <module>
    prepare_data(conn)
  File "dumpCamera1.py", line 86, in prepare_data
    create_task(conn, task)
  File "dumpCamera1.py", line 79, in create_task
    cur = conn.cursor()
sqlite3.ProgrammingError: Cannot operate on a closed database.
  

Не уверен, где мое соединение закрывается. Возможно, вы сделали что-то очень глупое, но были бы признательны за указатели?

Спасибо.

Ответ №1:

finally Предложение в create_connection функции закрывает соединение до того, как оно будет возвращено.

Похоже, что вы пытаетесь создать своего рода контекстный менеджер для соединения, но соединение с sqlite3 уже является контекстным менеджером, так что в этом нет необходимости.

Вы можете сделать

 with sqlite3.connect(dbfile) as conn:
    print(sqlite3.version)
    prepare_data(conn)
  

Соединение будет автоматически закрыто при выходе из диспетчера контекста. Вы можете перехватывать ошибки, возникающие внутри диспетчера контекста, заключая их в try / except блок.