I want to explicitly create all DB tables in an empty database myself via migration. How can I do this?
Room always creates initial tables itself using entity classes. This is an unreliable approach. I can't control schema and have to rely on Room.
CodePudding user response:
Room always creates initial tables itself using entity classes. This is an unreliable approach.
It is not unreliable in fact the opposite. However, what should be understood is that Room is about storing and retrieving objects when the underlying database manager, SQLite, has no concept of objects, just tables with columns. As such Room has to be able to create the objects (Entities) from the columns in a row or rows and hence rules that must be met. If met then Room is quite reliable.
I can't control schema and have to rely on Room.
You can and do by the way of coding the entities. However, the rules come with limitations or perhaps more correctly proper/formal use of SQLite. So you have control over the schema but it must adhere to Room's rules/limitations.
An example is column types.
SQLite has a very flexible approach to column types. In that virtually anything can be a accepted as a column type.
Room however, must know how to store/extract the object (entity). As such Room restricts column types to INTEGER, TEXT, REAL or BLOB (the 4 types that SQLite supports). Room does not support the catch-all NUMERIC type and it does not support SQLite's conversion of other column types to a type via SQLite's rule for determining type affinity.
- Room is NEVER going to accept a column defined as
timestamp DATE
as an example as DATE is not one of INTEGER, TEXT, REAL or BLOB (in SQLite DATE resolves to a type affinity of NUMERIC, the catch all).
- Room is NEVER going to accept a column defined as
I want to explicitly create all DB tables in an empty database myself via migration. How can I do this?
In short do one of the following:
- Follow Room's rules when defining the schema,
- Be smart and let Room do the work (as explained below), or
- Use native SQLite rather than Room.
The smart way, as you must have Entities, is to create the Entities and the class annotated with @Database and then compile. Doing so will generate code with the
expected
schema. The generated code is in the generated java, visible via the Android View in Android Studio. It is in the class that is the name of the class annotated with @Database suffixed with _Impl. In thecreateAllTables
method are the create table SQL statements that Room uses if and when Room creates the tables. This is what Room expects and will adhere to the rules.You can then use the SQL created by Room as the basis for creating or modifying tables.
You can do many things in the Migration. The creation of new tables, if new tables are introduced, would be a requirement as the Migration is passed an unchanged database. It is the job of the Migration to alter the database and thus create new tables if that is required according to the Entities defined in the @Database annotation.