Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Base de datos SQLite de Android, ¿POR QUÉ caída de tabla y volver a crear en la actualización

En los tutoriales que estoy siguiendo y un montón de lugares más veo esto, onUpgrade -> drop table si existe, a continuación, recrear la tabla.

¿Cuál es el propósito de esto?

private static class DbHelper extends SQLiteOpenHelper{ public DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_NAME + " TEXT NOT NULL, " + KEY_HOTNESS + " TEXT NOT NULL);" ); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE); onCreate(db); } } 

  • Cómo construir una consulta SQLite a GROUP by ORDER?
  • Sqlite eliminar la sintaxis de consulta en Android
  • Recyclerview + Proveedor de contenido + CursorLoader
  • No pudo leer la fila 0, la columna -1
  • Android SQLite Query - Obteniendo los últimos 10 registros
  • ¿Podemos actualizar el APK en Google Play Store sin cambiar la versión de APP
  • SQLITE - eliminar filas con join interno?
  • SQlite - Android - Sintaxis de clave extranjera
  • 5 Solutions collect form web for “Base de datos SQLite de Android, ¿POR QUÉ caída de tabla y volver a crear en la actualización”

    Estoy de acuerdo cuando se actualiza debe agregar columnas o agregar tablas a su base de datos. La mayoría de las muestras de onupgrade realmente chupar porque ¿por qué estoy borrando todos estos datos y luego recrear la tabla? Encontré esta entrada de blog que llamo el método de actualización incremental Adams . También maneja situaciones en las que los usuarios pueden no haber actualizado su aplicación con cada versión.

    Aquí hay un buen blog en sqlite onupgrade que no hace drop table.

    Bueno, el método más común en las aplicaciones de Android es "relog" al usuario cuando una actualización de la base de datos está en orden. Y teniendo en cuenta cualquier base de datos local sólo debe reflejar lo que está en la aplicación serverside, es mucho más fácil simplemente dejar caer la base de datos, volver a crear y repoblar desde el servidor que es cuidadosamente planificar las migraciones de una versión a la otra.

    Ciertamente no es el mejor enfoque, pero es más fácil.

    Para dar un ejemplo de cómo se estaría implementando una migración (un cambio de una versión anterior de una base de datos a otra más reciente)

    Digamos que en su clase DbHelper define que su base de datos es la versión 1, en una versión posterior de su aplicación (versión 2), necesita unas cuantas columnas más en una de sus tablas.

    Así que necesitará actualizar su tabla y agregar las columnas a través de ALTER TABLE {tableName} AÑADIR COLUMNA COLNew {type};

    Compruebe este enlace para que -> Insertar nueva columna en la tabla en sqlite?

    Por lo que su método onUpgrade() tendría que reflejar ese cambio agregando:

      @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { switch(oldVersion){ case 1: db.execSQL("ALTER TABLE " + DATABASE_TABLE + " ADD COLUMN " + NEW_COLUMN_NAME + TYPE); } } 

    Depende del tipo de enfoque que desea crear y la importancia de sus datos, lo que la complejidad de la tabla es. Ejemplo: Si su aplicación se ha actualizado bastante tiempo y la estructura de la tabla ha cambiado bastante veces, entonces es mejor dejar la tabla y volver a crearla, en lugar de escribir código para cambiar la estructura de cada versión de db, en este enfoque usted Tendrá que asegurarse de que puede hacer copias de seguridad de los datos que tenga en el lado del servidor, por lo que las cosas siguen siendo bien.

    De mi exp: recrear es mejor si se puede juzgar que podría haber más cambios en el futuro, de lo contrario se vuelve bastante complicado

    Es un comienzo limpio. El método onCreate tiene la estructura de base de datos actualmente válida. Los usuarios que instalen la aplicación ejecutarán este método. Para los usuarios que están actualizando, el método onUpgrade será ejecutado, y DROP TABLE SI EXIST es un comienzo limpio – sólo en caso de que la estructura de la tabla nueva y la nueva sea diferente – dejarlo y luego volver a crearlo en el método onCreate. ¡Espero que esto ayude! 🙂

    Si desea mantener los datos de la tabla, puede volcarlos en archivos CSV y luego INSERTARlos de nuevo una vez creadas las tablas. (No es necesario descargar los datos en un servidor) aquí hay un código de ejemplo para el dumping de datos. Puede definir el nombre del archivo como el nombre de la tabla. El cursor se crea a partir de una sentencia getAll

     public boolean createCsvSaveToFile(Cursor cursor, String fileName) throws IOException { String csv = ""; int colunmCount = cursor.getColumnCount(); /* check if extarnal drive is readerble */ if (!isExternalStorageWritable()) { fileError = "can not save to external storage"; fileinfo = "Please mount your SD card"; return false; } else { /* create the CSV */ for (int i = 0; i < colunmCount; i++) { csv += QUOTES + cursor.getColumnName(i).toString() + QUOTES + INNER_DELIMITER; } csv = csv.replaceAll(",$", ""); csv += LINE_END; if (cursor.moveToFirst()) { do { for (int i = 0; i < colunmCount; i++) {//GET COLUNM values csv += QUOTES + cursor.getString(i) + QUOTES + INNER_DELIMITER; } csv = csv.replaceAll(",$", ""); csv += LINE_END; } while (cursor.moveToNext()); } /* save file */ File file = getDataDir(fileName); FileOutputStream out = new FileOutputStream(file); out.write(csv.getBytes()); out.flush(); out.close(); return true; } } 

    Aquí hay un código de ejemplo para insertar los datos. Suponiendo que el nombre del archivo CSV es el mismo que el nombre de la tabla

     private void readFromFile(SQLiteDatabase database, File file) { boolean hasColunms = false; String tableName = file.getName().replaceAll(".csv$", ""); String sql; String colunmNames = ""; String colunmValues; try { BufferedReader br = new BufferedReader(new FileReader(file)); String line; while ((line = br.readLine()) != null) { if (!hasColunms ) { /* get column names */ line = line.replaceAll("\"", ""); colunmNames = line; hasColunms = true; } else { line = line.replaceAll("\"", "'"); colunmValues = line; sql = "INSERT INTO " + tableName + " (" + colunmNames + ") VALUES (" + colunmValues + ")"; database.execSQL(sql); } } br.close(); } catch (IOException e) { database.close(); /* You may need to add proper error handling here } 

    Para realizar bucle a través de muchos archivos csv se puede usar el siguiente código

     public boolean csvTodatabase(SQLiteDatabase database) { FileStuff f = new FileStuff(); File time; /* check if extarnal drive is readerble */ if (!f.isExternalStorageReadable()) { f.fileError = "can not read external storage"; f.fileinfo = "Please remount your SD card"; return false; } else { /* get all files from extarnal drive data */ ArrayList<File> files = new ArrayList<File>(); File directory = new File(FileStuff.DATA_DIRECTORY); if (!directory.exists()) { return false; } File[] fList = directory.listFiles(); for (File file : fList) { if (file.isFile()) { files.add(file); } } for (File csvfile : files) { readFromFile(database, csvfile); } return true; } } 

    NOTA: readFromFile (base de datos, archivo csv); Es la función anterior

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