Путаница: как работает SQLiteOpenHelper onUpgrade ()? И вместе с импортом старой резервной копии базы данных?

Допустим, у меня есть таблица базы данных test_table с 2 столбцами и соответствующий сценарий создания в SQLiteOpenHelper:

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

Это начальная версия приложения 1, которая публикуется в Play Маркете.

Через некоторое время обновляется приложение и используемая база данных. Я думаю, что класс SQLiteOpenHelper должен быть адаптирован следующим образом:

 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"); } 

Через некоторое время обновится другое приложение:

 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"); } 

-> Здесь мне нужен совет. Если пользователь устанавливает приложение 1, у него есть столбцы A и B. Если он затем обновляется до версии 2, onUpgrade запускает и добавляет столбец C. Новые пользователи, которые устанавливают с нуля, получают три столбца через инструкцию create. Если пользователь затем обновляется до версии 3, onUpgrade запускается снова и добавляется столбец D. Но ЧТО ЕСЛИ пользователь устанавливает приложение 1, а затем пропускает обновление версии 2 и обновляет версию 3? Тогда он бы пропустил

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

Часть и только

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

Будет вызываться, что приводит к таблице test_table (COL_A, COL_B, COL_D) ??

Каков правильный способ обработки обновлений базы данных в реальном времени, поэтому пользователь не потеряет свои данные? Нужно ли проверять все возможные (старые) версии в методе onUpgrade () и выполнять разные инструкции таблиц alter на основе этой версии?

Я спрашиваю, потому что в моем приложении пользователь имеет возможность экспортировать и импортировать данные, что является не чем иным, как экспортом: скопируйте всю базу данных и импортируйте: замените базу данных приложения резервной копией базы данных.

Что произойдет, если пользователь имеет приложение версии 1, экспортирует базу данных, обновляет приложение (новая структура базы данных) и импортирует резервную копию старой версии 1? -> Как будет вести себя SQLiteOpenHelper? -> Каков правильный способ обработки обновлений db вместе с функциями импорта / экспорта?

Solutions Collecting From Web of "Путаница: как работает SQLiteOpenHelper onUpgrade ()? И вместе с импортом старой резервной копии базы данных?"

Каков правильный способ обработки обновлений базы данных в реальном времени, поэтому пользователь не потеряет свои данные? Нужно ли проверять все возможные (старые) версии в методе onUpgrade () и выполнять разные инструкции таблиц alter на основе этой версии?

По большому счету, да.

Общий подход к этому заключается в том, чтобы сделать пару обновления:

 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 } 

Например, это примерно соответствует миграции Rails.

Что произойдет, если пользователь имеет приложение версии 1, экспортирует базу данных, обновляет приложение (новая структура базы данных) и импортирует резервную копию старой версии 1? -> Как будет вести себя SQLiteOpenHelper?

Если «скопировать всю базу данных», вы буквально означаете полную копию файла базы данных SQLite, а затем, когда SQLiteOpenHelper откроет восстановленную резервную копию, она будет иметь версию старой схемы и будет проходить через onUpgrade() как обычно.

Каков правильный способ обработки обновлений db вместе с функциями импорта / экспорта?

Я подозреваю, что ответ: либо сделайте резервную копию, скопировав весь файл, либо также организуйте резервное копирование и восстановление версии схемы, которую вы можете получить, вызвав getVersion() в объекте SQLiteDatabase . Это, как говорится, я не рассматривал этот сценарий много, и может быть больше проблем, о которых я не думаю.

Ниже кода psuedo показано повышение уровня

 @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)); } } 

По инкрементному обновлению я имею в виду – Обратите внимание на отсутствующий оператор break в случаях 2 и 3

Скажем, если старая версия равна 2, а новая версия – 4, то логика обновит базу данных с 2 до 3, а затем до 4

Если старая версия 3, а новая версия – 4, она просто запустит логику обновления от 3 до 4

Продолжайте добавлять новые случаи для каждой новой версии обновления базы данных, которая будет делать дополнительные изменения

Я подозреваю, что вы также можете создать новую таблицу со всеми необходимыми столбцами

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; старую таблицу DROP TABLE test_table;

И переименуйте новую таблицу

ALTER TABLE new_test_table RENAME TO test_table;

Так короче

 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;");" } 

Таким образом вам не нужно беспокоиться о dataloss или дополнительных изменениях

В Android-Database-Upgrade-Tutorial вы найдете подробное руководство по тому, как вы обрабатываете расширенную схему вашей схемы базы данных приложения при выпуске новых версий приложений.

Учебник состоит из приложения, имеющего 4 версии, каждая версия содержит различное количество столбцов, Различные варианты применения

Это разные сценарии, с которыми можно столкнуться Различные сценарии