¿Cuándo se ejecuta SQLiteOpenHelper onCreate()/onUpgrade()?

Resuelto laalto asked hace 54 años • 15 respuestas

He creado mis tablas en mi SQLiteOpenHelper onCreate()pero recibo

SQLiteException: no such table

o

SQLiteException: no such column

errores. ¿Por qué?

NOTA:

(Este es el resumen combinado de decenas de preguntas similares cada semana. Intentamos proporcionar una pregunta/respuesta wiki de la comunidad "canónica" aquí para que todas esas preguntas puedan dirigirse a una buena referencia).

laalto avatar Jan 01 '70 08:01 laalto
Aceptado

SQLiteOpenHelper onCreate()y onUpgrade()las devoluciones de llamada se invocan cuando la base de datos se abre realmente, por ejemplo mediante una llamada a getWritableDatabase(). La base de datos no se abre cuando se crea el objeto auxiliar de la base de datos.

SQLiteOpenHelperversiona los archivos de la base de datos. El número de versión es el intargumento pasado al constructor . En el archivo de base de datos, el número de versión se almacena en formato PRAGMA user_version.

onCreate()solo se ejecuta cuando el archivo de base de datos no existía y recién se creó. Si onCreate()regresa exitosamente (no arroja una excepción), se supone que la base de datos se creó con el número de versión solicitado. Como implicación, no deberías atrapar SQLExceptions en onCreate()ti mismo.

onUpgrade()solo se llama cuando el archivo de base de datos existe pero el número de versión almacenada es inferior al solicitado en el constructor. Deben onUpgrade()actualizar el esquema de la tabla a la versión solicitada.

Al cambiar el esquema de la tabla en el código ( onCreate()), debe asegurarse de que la base de datos esté actualizada. Dos enfoques principales:

  1. Elimine el archivo de base de datos antiguo para que onCreate()se ejecute nuevamente. Esto suele ser preferible en el momento del desarrollo, donde se tiene control sobre las versiones instaladas y la pérdida de datos no es un problema. Algunas formas de eliminar el archivo de base de datos:

    • Desinstale la aplicación. Utilice el administrador de aplicaciones o adb uninstall your.package.namedesde el shell.

    • Borrar datos de la aplicación. Utilice el administrador de aplicaciones.

  2. Incrementar la versión de la base de datos para que onUpgrade()se invoque. Esto es un poco más complicado ya que se necesita más código.

    • Para actualizaciones del esquema de tiempo de desarrollo donde la pérdida de datos no es un problema, puede usar execSQL("DROP TABLE IF EXISTS <tablename>")in para eliminar las tablas existentes y llamar onCreate()para recrear la base de datos.

    • Para las versiones publicadas, debe implementar la migración de datos onUpgrade()para que sus usuarios no pierdan sus datos.

laalto avatar Feb 19 '2014 13:02 laalto

Para agregar más puntos faltantes aquí, según la solicitud de Jaskey

La versión de la base de datos se almacena dentro del SQLitearchivo de la base de datos.

captura es el constructor

SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

Entonces, cuando se llama al constructor auxiliar de la base de datos con un name(segundo parámetro), la plataforma verifica si la base de datos existe o no y, si la base de datos existe, obtiene la información de la versión del encabezado del archivo de la base de datos y activa la devolución de llamada correcta.

Como ya se explicó en la respuesta anterior, si la base de datos con el nombre no existe, se activa onCreate.

La siguiente explicación explica onUpgradeel caso con un ejemplo.

Digamos que su primera versión de la aplicación tenía DatabaseHelper(extendido SQLiteOpenHelper) con el constructor pasando la versión como 1y luego proporcionó una aplicación actualizada con el nuevo código fuente con la versión pasada como 2, luego, automáticamente, cuando se DatabaseHelperconstruye, la plataforma se activa onUpgradeal ver que el archivo ya existe. pero la versión es inferior a la versión actual que aprobó.

Ahora digamos que está planeando ofrecer una tercera versión de la aplicación con la versión db como 3(la versión db aumenta solo cuando se va a modificar el esquema de la base de datos). En dichas actualizaciones incrementales, debe escribir la lógica de actualización de cada versión de forma incremental para obtener un código mejor mantenible.

Pseudocódigo de ejemplo a continuación:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  switch(oldVersion) {
    case 1:
       //upgrade logic from version 1 to 2
    case 2:
       //upgrade logic from version 2 to 3
    case 3:
       //upgrade logic from version 3 to 4
       break;
    default:
       throw new IllegalStateException(
                "onUpgrade() with unknown oldVersion " + oldVersion);
  }
}

Observe la breakdeclaración que falta en caso 1y 2. Esto es lo que quiero decir con actualización incremental.

Digamos que si la versión anterior es 2y la nueva es 4, entonces la lógica actualizará la base de datos de 2a 3y luego a4

Si la versión anterior es 3y la nueva es 4, simplemente ejecutará la lógica de actualización 3para4

Aun avatar Nov 13 '2014 19:11 Aun

onCreate()

  1. Cuando creamos una base de datos por primera vez (es decir, la base de datos no existe), onCreate()creamos una base de datos con la versión que se pasa. SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

  2. onCreate()El método es crear las tablas que has definido y ejecutar cualquier otro código que hayas escrito. Sin embargo, este método solo se llamará si falta el archivo SQLite en el directorio de datos de su aplicación ( /data/data/your.apps.classpath/databases).

  3. No se llamará a este método si cambiaste tu código y lo reiniciaste en el emulador. Si desea onCreate()ejecutar, debe usar adb para eliminar el archivo de base de datos SQLite.

onUpgrade()

  1. SQLiteOpenHelperdebería llamar al superconstructor.
  2. El onUpgrade()método solo se llamará cuando el número entero de la versión sea mayor que la versión actual que se ejecuta en la aplicación.
  3. Si desea onUpgrade()que se llame al método, debe incrementar el número de versión en su código.
jeet parmar avatar Jun 16 '2015 13:06 jeet parmar

Quizás sea demasiado tarde, pero me gustaría compartir mi breve y concisa respuesta. Por favor marque Respuesta para el mismo problema. Definitivamente te ayudará. No más especificaciones profundas.

Si tiene confianza en la sintaxis para crear una tabla, esto puede suceder cuando agrega una nueva columna en la misma tabla, por eso...

1) Desinstale de su dispositivo y ejecútelo nuevamente.

O

2) Configuración -> aplicación -> ClearData

O

3) Cambie DATABASE_VERSIONsu clase "DatabaseHandler" (si ha agregado una nueva columna, se actualizará automáticamente)

public DatabaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

O

4) Cambie DATABASE_NAMEsu clase "DatabaseHandler" (me enfrenté al mismo problema, pero lo logré al cambiar DATABASE_NAME).

shital avatar Mar 06 '2017 06:03 shital