2009-10-09 11 views
29

El mensaje de error que estoy tratando de deshacerse de es:Fuerza Python renunciar sqlite3 nativo y usar la versión más reciente sqlite3 (instalado)

AttributeError: 'sqlite3.Connection' object has no attribute 'enable_load_extension'

tengo 'easy_install'-ed la versión más reciente sqlite3 y Python de alguna manera sabe que está allí ya que sqlite3.version_info produce 3.6.13. En esta versión, Connection debe tener el atributo 'enable_load_extension'.

Lo que creo que está pasando es que python todavía usa el módulo nativo sqlite3 que creo que es 2.4.1 ya que sqlite3.version (i.s.o. sqlite3.version_info) produce 2.4.1.

La pregunta es ¿cómo fuerzo a Python a usar el nuevo módulo sqlite3 para todas las llamadas sqlite3?

Respuesta

63

sqlite3 apoyo en Python puede ser un poco confuso. El adaptador de base de datos sqlite comenzó como un proyecto separado, pysqlite2, pero para Python 2.5 se incorporó una versión de la biblioteca estándar de Python con el nombre sqlite3. El adaptador original continúa desarrollándose como ese proyecto separado, mientras que periódicamente la versión en Python se actualiza para que coincida. Si está intentando utilizar una versión más reciente del adaptador, por lo general se instala como pysqlite2 para no entrar en conflicto con la versión incluida en la biblioteca estándar. Y, dependiendo de cómo fue construido, puede vincular a una versión diferente del sqlite3 database library subyacente. Así que asegúrese de que está importando correctamente:

>>> import sqlite3 
>>> sqlite3.version_info 
(2, 4, 1) 
>>> sqlite3.sqlite_version_info 
(3, 6, 11) 

>>> from pysqlite2 import dbapi2 as sqlite3 
>>> sqlite3.version_info 
(2, 5, 5) 
>>> sqlite3.sqlite_version_info 
(3, 6, 18) 

version_info es la versión de la sqlite3 (pysqlite2 o incorporada sqlite3) adaptador de la base de datos. sqlite_version_info es la versión de la biblioteca de base de datos subyacente sqlite3.

Se recomienda usar from ... import ... as sqlite3 para que el resto de su código no tenga que cambiar si pasa de una versión a otra.

Nota, enable_load_extension apareció por primera vez en pysqlite2 2.5.0.

EDIT:enable_load_extension está deshabilitado de forma predeterminada al compilar el adaptador. Para habilitarlo, puede compilar manualmente pysqlite2. La siguiente receta asume un sistema unix -y y la última versión de pysqlite2, que a partir de este momento es 2.5.5.

En primer lugar, si ha instalado el adaptador originalmente a través de easy_install, desinstala por primera ejecución:

$ sudo /path/to/easy_install -m pysqlite # or whatever package name you first used 

Habrá alguna salida desde que la inclusión de líneas como:

Removing pysqlite 2.5.5 from easy-install.pth file 

Using /path/to/site-packages/pysqlite-2.5.5-py2.x-something.egg 

Retire el huevo usando el nombre del archivo listado (el nombre variará según su plataforma y versión y puede referirse a un archivo o directorio):

$ sudo rm -r /path/to/site-packages/pysqlite-2.5.5-py2.x-something.egg 

Ahora descargar y extraer el archivo tar pysqlite-2.5.5 fuente:

$ mkdir /tmp/build 
$ cd /tmp/build 
$ curl http://oss.itsystementwicklung.de/download/pysqlite/2.5/2.5.5/pysqlite-2.5.5.tar.gz | tar xz 
$ cd pysqlite-2.5.5 

luego editar el archivo setup.cfg a comentar la Directiva SQLITE_OMIT_LOAD_EXTENSION:

$ ed setup.cfg <<EOF 
> /SQLITE_OMIT_LOAD_EXTENSION/s/define=/#define=/ 
> w 
> q 
> EOF 

Desde la versión de sqlite3 es tan viejo (3.4.0), también debería compilar con la última biblioteca sqlite3. Esto es fácil en el guión pysqlite2 setup.py:

$ /path/to/python2.x setup.py build_static 

Esto descargará automáticamente la última sqlite3 amalgamation source y construir el adaptador junto con una versión actualizada vinculados estáticamente de sqlite3. Este paso puede tomar un tiempo largo para terminar.

ACTUALIZACIÓN (21/07/2015): Según el último pysqlite 2.6.3 commit que tiene que descargar el código fuente sqlite por sí mismo y los puso en la carpeta raíz pysqlite.

Ahora, instalar el adaptador:

$ sudo /path/to/python2.x setup.py install 

y ejecutar las pruebas:

$ cd  # somewhere out of the build directory 
$ /path/to/python2.x 
>>> from pysqlite2 import test 
>>> test.test() 

y, si pasan, usted debe estar todo listo.

Como beneficio adicional, si la razón por la que quiere apoyo a la extensión de carga es utilizar sqlite3 's extensión de búsqueda de texto completo, FTS3, usted debe encontrar que estaba incluido como parte de la biblioteca estática y no es necesario seguir trabajando:

>>> from pysqlite2 import dbapi2 as sqlite3 
>>> con = sqlite3.connect(":memory:") 
>>> con.execute("create virtual table recipe using fts3(name, ingredients)") 
<pysqlite2.dbapi2.Cursor object at 0xca5e0> 
+0

Estimado Ned: Esto seguramente me ha ayudado mucho - ¡gracias! Ahora mi script de python parece cargar la versión más reciente del adaptador después de usar la construcción 'from ... import ... as sqlite3', ya que obtengo 2.5.5 para version_info y 3.4.0 para sqlite_version. Sin embargo, una línea más, trato de usar 'enable_load_extension' y ahora obtengo: AttributeError: el objeto 'pysqlite2.dbapi2.Connection' no tiene ningún atributo 'enable_load_extension' Por toda la información que me ha dado esto parece ser sorprendente , ¿no? Muchas gracias por su ayuda hasta el momento, ¡realmente apreciada! --Albert – Albert

+0

¡Maldición! He expandido la respuesta para incluir cómo construir el adaptador con soporte de extensión de carga habilitado y con una versión actualizada de la biblioteca sqlite3. –

+0

Ned, gracias por su rápida respuesta. He seguido tus instrucciones literalmente. Mi sistema ahora tiene la última versión de sqlite3. Sin embargo, si escribo 'desde pysqlite2 import test', aparece el siguiente error: desde pysqlite2._sqlite import * ImportError: dlopen (/Library/Python/2.5/site-packages/pysqlite2/_sqlite.so, 2) : Símbolo no encontrado: _sqlite3_enable_load_extension referencia desde: /Library/Python/2.5/site-packages/pysqlite2/_sqlite.so esperado en:. dinámicas de búsqueda :(, lo siento que te moleste de nuevo con esto me siento muy cerrar ahora ... Muchas gracias (!) por toda tu ayuda hasta ahora, Albert – Albert

3

Necesita ver su ruta de Python y asegurarse de que la sqlite que desea esté instalada en un directorio anterior a la sqlite incorporada.

se puede ver el camino con:

import sys 
print sys.path 

Si desea averiguar dónde un módulo es de, tratar:

print sqlite3.__file__ 
+0

Estimado Ned: Esto es muy útil, ¡muchas gracias! Siento que ahora estoy mucho más cerca de resolver completamente el problema después de tu comentario y el publicado por Ned Deily. --Albert – Albert

13

Tengo python 2.7 en una máquina con Windows y la función sqlite3.sqlite_version incorporada es 3.6.x. Al realizar los siguientes pasos, pude hacer que utilizara sqlite 3.7.9.

  1. Descarga y descomprime el archivo DLL binario precompilado ("sqlite-dll-win32-x86-3070900.zip" en http://www.sqlite.org/download.html)
  2. (probablemente debería cerrar todas las instancias de pitón en este punto sólo para estar seguro) Vaya a C: \ Python27 \ DLLs y cambie el nombre de archivo de "sqlite3.dll" a "sqlite3.dll.old"
  3. Copie el archivo "sqlite3.DLL" a la carpeta C: \ python27 \ DLL
  4. abierto pitón cáscara y la importación sqlite3
  5. Verificar sqlite3.sqlite_version se muestra como '3.7.9'
+0

Gracias Will. Sin embargo, me pregunto si no hay riesgo de incompatibilidad entre el nuevo sqlite3.dll y el pitón 2.7. código del paquete sqlite3. Supongo que el paquete sqlite3 fue probado contra un sqlite3.dll en particular y su API puede evolucionar a tiempo. Tal vez tuvo suerte con estas versiones particulares y escenarios de prueba ... ¿O hay un banco de pruebas? – dim

+0

Hola Dim, no hice ninguna prueba, ¡así que es posible que haya tenido suerte! –

+0

Funcionó bien para mí. –

3

En lugar del módulo estándar de Python sqlite3, se podría ser capaz de usar el módulo apsw, un módulo SQLite de terceros que sigue más de cerca la API de SQLite. Incluye soporte para cargar extensiones, así como básicamente todo lo que está permitido en la API SQLite C/C++. tanto como sea posible para mantenerse al día con cualquier cambio nuevo en SQLite.