Confusión: ¿Cómo se comporta SQLiteOpenHelper onUpgrade ()? Y junto con la importación de una copia de seguridad de base de datos de edad?

Supongamos que tengo una tabla de base de datos test_table con 2 columnas y un script de creación correspondiente en el SQLiteOpenHelper:

DB_VERSION = 1: public void onCreate(SQLiteDatabase db) { db.execSql("CREATE table test_table (COL_A, COL_B); } 

Esta es la versión 1 de la aplicación inicial, que se publica en Play Store.

Después de un tiempo hay una actualización de la aplicación y la base de datos utilizada. Supongo que la clase SQLiteOpenHelper tiene que adaptarse de esta manera:

 DB_VERSION = 2: public void onCreate(SQLiteDatabase db) { db.execSql("CREATE table test_table (COL_A, COL_B, COL_C)"); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSql("ALTER TABLE test_table ADD Column COL_C"); } 

Después de algún tiempo, otra actualización de la aplicación:

 DB_VERSION = 3: public void onCreate(SQLiteDatabase db) { db.execSql("CREATE table test_table (COL_A, COL_B, COL_C, COL_D)"); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSql("ALTER TABLE test_table ADD Column COL_D"); } 

-> Aquí es donde necesito consejo. Si el usuario instala la versión 1 de la aplicación, tiene las columnas A y B. Si se actualiza a la versión 2, onUpgrade se enciende y agrega una columna C. Los nuevos usuarios que instalan desde cero obtienen las 3 columnas mediante la sentencia create. Si el usuario se actualiza a la versión 3, onUpgrade se activa de nuevo y se agrega una columna D. Pero ¿QUÉ ES SI el usuario instala la aplicación versión 1, luego salta la actualización de la versión 2 y actualiza la versión 3? Entonces habría perdido la

 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSql("ALTER TABLE test_table ADD Column COL_C"); } 

Parte y solo

 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSql("ALTER TABLE test_table ADD Column COL_D"); } 

Sería llamado, lo que conduce a una table test_table (COL_A, COL_B, COL_D) ??

¿Cuál es la forma correcta de gestionar actualizaciones de bases de datos de una aplicación en vivo, por lo que el usuario no pierde sus datos? ¿Tiene que comprobar todas las versiones posibles (antiguas) en el método onUpgrade () y ejecutar distintas instrucciones de tabla alteradas basadas en esa versión?

Estoy preguntando porque en mi aplicación, el usuario tiene la posibilidad de exportar e importar los datos, que no es más que exportación: copiar toda la base de datos de distancia e importar: reemplazar la base de datos de la aplicación con la copia de seguridad de base de datos.

¿Qué sucede si el usuario tiene la versión 1 de la aplicación, exporta la base de datos, actualiza la aplicación (nueva estructura de base de datos) e importa la copia de seguridad de la versión 1 anterior? -> ¿Cómo se comportará SQLiteOpenHelper? -> ¿Cuál es la manera correcta de manejar las actualizaciones db junto con la funcionalidad de importación / exportación?

¿Cuál es la forma correcta de gestionar actualizaciones de bases de datos de una aplicación en vivo, por lo que el usuario no pierde sus datos? ¿Tiene que comprobar todas las versiones posibles (antiguas) en el método onUpgrade () y ejecutar distintas instrucciones de tabla alteradas basadas en esa versión?

En general, sí.

Un acercamiento común a esto es hacer actualizaciones par-wise:

 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion<2) { // do upgrade from 1 to 2 } if (oldVersion<3) { // do upgrade from 2 to 3, which will also cover 1->3, // since you just upgraded 1->2 } // and so on } 

Esto equivale aproximadamente a las migraciones de Rails, por ejemplo.

¿Qué sucede si el usuario tiene la versión 1 de la aplicación, exporta la base de datos, actualiza la aplicación (nueva estructura de base de datos) e importa la copia de seguridad de la versión 1 anterior? -> ¿Cómo se comportará SQLiteOpenHelper?

Si por "copiar toda la base de datos de distancia", significa literalmente una copia completa del archivo de base de datos SQLite, a continuación, cuando SQLiteOpenHelper va a abrir la copia de seguridad restaurada, que la base de datos tiene la versión del esquema antiguo y pasará por onUpgrade() como normal.

¿Cuál es la manera correcta de manejar las actualizaciones de db junto con la funcionalidad de importación / exportación?

Sospecho que la respuesta es: o hacer su copia de seguridad copiando todo el archivo, o también organizar la copia de seguridad y restaurar la versión del esquema, que puede obtener llamando a getVersion() en un objeto SQLiteDatabase . Dicho esto, no he abordado este escenario mucho, y puede haber más problemas que no estoy pensando.

Debajo del código psuedo muestra la actualización incremental

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

Por actualización incremental quiero decir – Observe la sentencia break faltante en el caso 2 y 3

Decir si la versión antigua es 2 y la nueva versión es 4, entonces la lógica actualizará la base de datos de 2 a 3 y luego a 4

Si la versión antigua es 3 y la nueva versión es 4, sólo se ejecutará la lógica de actualización de 3 a 4

Siga añadiendo nuevos casos para cada nueva versión de la base de datos de actualización que hará los cambios incrementales

Sospecho que también puede crear una nueva tabla con todas las columnas que necesita

CREATE TABLE new_test_table (COL_A, COL_B, COL_C,COL_D);

Copiar los datos de la tabla antigua a la nueva

INSERT INTO new_test_table SELECT * FROM test_table;

Soltar la tabla antigua DROP TABLE test_table;

Y cambiar el nombre de la nueva tabla

ALTER TABLE new_test_table RENAME TO test_table;

En resumen

 public void onUpgrade(SQLiteDatabase db,int OldVersion,int NewVersion){ db.execSQL("CREATE TABLE new_test_table (COL_A, COL_B, COL_C,COL_D);"+ "INSERT INTO new_test_table SELECT * FROM test_table;"+ "DROP TABLE test_table;"+ "ALTER TABLE new_test_table RENAME TO test_table;");" } 

De esa manera usted no tiene que preocuparse de dataloss o cambios incrementales

Android-Database-Upgrade-Tutorial muestra la guía completa de cómo manejar la mejora de la aplicación del esquema de la base de datos al liberar nuevas versiones de la aplicación.

El tutorial consiste en la aplicación que tiene 4 versión, cada versión que contiene el número diferente de columnas, Diferentes versiones de la aplicación

Estos son los diferentes escenarios que uno puede enfrentar Diferentes escenarios

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.