Saltar al contenido

¿Cómo verificar si existe una base de datos SQLite3 en Python?

Por fin después de mucho batallar hemos encontrado la respuesta de este inconveniente que ciertos lectores de esta web tienen. Si quieres aportar alguna información puedes aportar tu conocimiento.

Solución:

En Python 2, deberá probar explícitamente la existencia usando os.path.isfile:

if os.path.isfile(db):

No hay manera de forzar la sqlite3.connect función para no crear el archivo para usted.


Para aquellos que usan Python 3.4 o más reciente, puede usar la nueva función de ruta URI para establecer un modo diferente al abrir una base de datos. los sqlite3.connect() función por defecto abrirá bases de datos en rwces decir Leer, escribir y crear modo, por lo que conectarse a una base de datos inexistente hará que se cree.

Usando un URI, puede especificar un modo diferente en su lugar; si lo configuras rwentonces Leer escribir modo, se genera una excepción al intentar conectarse a una base de datos inexistente. Puede configurar diferentes modos cuando configura el uri=True bandera al conectar y pasar en un file: URI y agregue un mode=rw parámetro de consulta a la ruta:

from urllib.request import pathname2url

try:
    dburi = 'file:?mode=rw'.format(pathname2url(db))
    conn = lite.connect(dburi, uri=True)
except sqlite3.OperationalError:
    # handle missing database case

Ver la URI de SQLite Parámetros de consulta reconocidos documentación para obtener más detalles sobre qué parámetros se aceptan.

os.path.isfile() ¡solo le dice si existe un archivo, no si existe Y es una base de datos SQLite3! Conociendo http://www.sqlite.org/fileformat.html, podría hacer esto:

def isSQLite3(filename):
    from os.path import isfile, getsize

    if not isfile(filename):
        return False
    if getsize(filename) < 100: # SQLite database file header is 100 bytes
        return False

    with open(filename, 'rb') as fd:
        header = fd.read(100)

    return header[:16] == 'SQLite format 3x00'

y posteriormente usarlo como:

for file in files:
    if isSQLite3(file):
        print "'%s' is a SQLite3 database file" % file
    else:
        print "'%s' is not a SQLite3 database file" % file

Sí, hay una forma de hacer lo que quieras con Python 3.4+.

Utilizar el sqlite3.connect() función para conectarse, pero pásele un URI en lugar de una ruta de archivo, y agregue mode=rw a su consulta string.

Aquí hay un ejemplo de código de trabajo completo:

import sqlite3
con = sqlite3.connect('file:aaa.db?mode=rw', uri=True)

Esto abrirá una base de datos existente desde un archivo llamado aaa.db en la carpeta actual, pero generará un error en caso de que ese archivo no se pueda abrir o no exista:

Traceback (most recent call last):
  File "aaa.py", line 2, in 
    con = sqlite3.connect('file:aaa.db?mode=rw', uri=True)
sqlite3.OperationalError: unable to open database file

Los documentos de Python sqlite.connect() establecen que:

si uri es true, la base de datos se interpreta como un URI. Esto le permite especificar opciones. Por ejemplo, para abrir una base de datos en modo de solo lectura, puede usar:

db = sqlite3.connect('archivo:ruta/a/base de datos?modo=ro', uri=Verdadero)

Puede encontrar más información sobre esta función, incluida una lista de opciones reconocidas, en la documentación de URI de SQLite.

Aquí hay un extracto de toda la información relevante de la opción URI recopilada de http://www.sqlite.org/c3ref/open.html:

modo: El parámetro de modo se puede establecer en "ro", "rw", "rwc" o "memoria". Intentar establecerlo en cualquier otro valor es un error. Si se especifica "ro", la base de datos se abre para acceso de solo lectura, como si el indicador SQLITE_OPEN_READONLY se hubiera establecido en el tercer argumento de sqlite3_open_v2(). Si la opción de modo se establece en "rw", la base de datos se abre para acceso de lectura y escritura (pero no para creación), como si se hubiera establecido SQLITE_OPEN_READWRITE (pero no SQLITE_OPEN_CREATE). El valor "rwc" es equivalente a configurar tanto SQLITE_OPEN_READWRITE como SQLITE_OPEN_CREATE. Si la opción de modo se establece en "memoria", se utiliza una base de datos pura en memoria que nunca lee ni escribe desde el disco. Es un error especificar un valor para el parámetro de modo que sea menos restrictivo que el especificado por las banderas pasadas en el tercer parámetro a sqlite3_open_v2().

los sqlite3_open_v2() La interfaz funciona como sqlite3_open() excepto que acepta dos parámetros adicionales para un control adicional sobre la nueva conexión a la base de datos. El parámetro flags de sqlite3_open_v2() puede tomar uno de los siguientes tres valores, opcionalmente combinado con los flags SQLITE_OPEN_NOMUTEX, SQLITE_OPEN_FULLMUTEX, SQLITE_OPEN_SHAREDCACHE, SQLITE_OPEN_PRIVATECACHE y/o SQLITE_OPEN_URI:

SQLITE_OPEN_READONLY La base de datos se abre en modo de solo lectura. Si la base de datos aún no existe, se devuelve un error.

SQLITE_OPEN_READWRITE La base de datos se abre para lectura y escritura si es posible, o solo lectura si el archivo está protegido contra escritura por el sistema operativo. En cualquier caso, la base de datos ya debe existir; de lo contrario, se devuelve un error.

SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE La base de datos se abre para lectura y escritura, y se crea si aún no existe. Este es el comportamiento que siempre se usa para sqlite3_open() y sqlite3_open16().

Para mayor comodidad, aquí también hay una función de Python 3.4+ para convertir una ruta normal en un URI utilizable por sqlite.connect():

import pathlib
import urllib.parse

def _path_to_uri(path):
    path = pathlib.Path(path)
    if path.is_absolute():
        return path.as_uri()
    return 'file:' + urllib.parse.quote(path.as_posix(), safe=':/')

Te mostramos comentarios y valoraciones

Si guardas algún titubeo o disposición de perfeccionar nuestro artículo puedes dejar una reseña y con deseo lo ojearemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *