rubezh-TWnlenfritplesuk

Миграции в ActiveAndroid

ActiveAndroid считается одной из лучших ORM для Android. Вот и я решил в одном из проектов ее испытать...

За удобство как известно нужно платить, вот и здесь мы расплачиваемся за удобство пользования скоростью работы с данными, особенно в режиме записи. В режиме чтения информации из БД разница практически не заметна, поэтому если Ваше приложение не очень часто записывает информацию в БД, то выбор в пользу ActiveAndroid вполне оправдан.

Но я хотел бы рассказать не о производительности, об этом много написано и на Хабре, и в блогах. Я хотел бы поведать о том, что же делать, если классы моделей Вашего приложения претерпели изменения в одной из версий, а данные на флешке телефона все еще в старом виде... 

Опишу ситуацию детальнее, с листингами кода.

Имеем некоторую модель, например:

package ru.dm_dev.vineyard.models;

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

@Table(name = "Areas", id = "_id")
public class Area extends Model {
@Column(name = "Name")
public String name;
}

При первом запуске приложения и инициализации ActiveAndroid, база данных создается на основе класса модели. В результате мы получим таблицу Areas с двумя столбцами: _id и Name.

Но вскоре понадобилось добавить одно поле в модель (таблицу):

  ...
  @Column
(name = "Description")
  public String description;
...

Если приложение будет установлено впервые на телефон, то все будет ОК: база данных соответствует модели - все счастливы!

Но при запуске приложения на телефоне, где уже имеется БД с данными пользователя мы получим исключение и приложение благополучно скрашится... И оно понятно - приложение в расчете на новую модель честно пытается считать из БД новое поле, а его там нет! Что делать?

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

Надо добавить новый столбец в таблицу! И благо язык SQL располагает данными командами, и в ActiveAndroid имеется инструментарий по автоматическому обновлению БД при запуске новой версии программы со старой версией БД. За изменения базы данных вслед за изменениями моделей данных отвечает механизм под названием - миграции.

Чтоб воспользоваться услугами механизма миграций, нужно соблюсти несколько простых правил:

1. В манифесте приложения помимо имени файла БД еще указывается номер версии структуры данных:

<meta-data android:name="AA_DB_VERSION" android:value="2" />

При изменении модели необходимо увеличить порядковый номер в этом файле. Здесь я уже увеличил номер - вместо 1 поставил 2.

2. Создать файл в папке приложения /app/assets/migrations/ со скриптом модификации БД, имя которого - текущий номер версии модели, т.е. 2.sql.

Например в данном примере это будет файл /app/assets/migrations/2.sql.

Изначально в проекте AndroidStudio папка assets отсутствует и судя по вопросам на StackOverflow многие не понимают где именно эту папку нужно создать. Постараюсь внести ясность в этот вопрос: чтоб создать папку assets необходимо правой кнопкой мыши щелкнуть по корневой папке app проекта:

Открытие папки проекта в проводнике

Затем выбрать пункт Show in Explorer. И в появившемся окне проводника последовательно открыть папки src и в ней main.

Путь к папке assets

И уже здесь создавать папку assets, а в ней migrations. Т.е. в файловой структуре на диске назначение будет следующим: d:\projects_path\project_name\app\src\main\assets\migrations\, где d:\projects_path - путь к папке с вашими проектами, project_name - название папки проекта. После создания необходимых папок - с ними можно будет работать они отобразятся в AndroidStudio, они автоматически там отобразятся. Нам же осталось совсем мало - создать файл миграции, он будет содержать перечень команд SQL, которые приведут БД в соответствие с новой моделью, в нашем случае это:

ALTER TABLE Area ADD COLUMN Description TEXT;

Собственно и все. После сборки и запуска проекта, программа при обнаружении отличий версии БД от версии модели, последовательно выполнит все необходимые файлы assets/migrations/*.sql для приведения базы в надлежащий вид. Теперь и обновлять программу можно без проблем, и пользователи будут благодарны тому что, с появлением нового функционала в Ваших программах, не будет пропадать его важная информация :)

P.S.: Стоит уточнить еще один нюанс в ActiveAndroid: в этой библиотеке нет возможности самостоятельно установить идентификатор записи (Primary Key), id новой записи присваивается библиотекой во время записи в базу, и методов внешнего воздействия на этот параметр нет. Поэтому в одном из приложений, в котором база имела достаточно сложную структуру и требовалось часто проводить обновление данных из внешнего источника (не только добавление, но и удаление и обновление), ну и отслеживать изменения внешних ключей было бы достаточно муторным занятием, в общем в этом приложении я принял решение в пользу библиотеки GreenDAO. Но об DAO-сизме как-нибудь в следующий раз.

1 1 1 1 1 1 1 1 1 1 Рейтинг 95%

Метки: java, android, orm, activeandroid

Печать E-mail

Добавить комментарий


Защитный код
Обновить