Oda - Şema dışa aktarma dizini ek açıklama işlemcisine sağlanmadığından şemayı dışa aktaramıyoruz


350

Android Veritabanı Bileşen Odası kullanıyorum

Her şeyi yapılandırdım, ancak derlediğimde Android Studio bana şu uyarıyı veriyor:

Şema dışa aktarma dizini ek açıklama işlemcisine sağlanmadığından şemayı dışa aktaramayız. room.schemaLocationEk açıklama işlemci bağımsız değişkeni sağlayabilir VEYA exportSchema öğesini false olarak ayarlayabilirsiniz.

Anladığım kadarıyla DB dosyasının bulunduğu konum

Uygulamamı nasıl etkileyebilir? Buradaki en iyi uygulama nedir? Varsayılan konumu ( falsedeğeri) kullanmalı mıyım ?

Yanıtlar:


396

Gereğince docs :

Room'a şemayı bir klasöre vermesini bildirmek için ek açıklama işlemcisi bağımsız değişkeni (room.schemaLocation) ayarlayabilirsiniz. Zorunlu olmasa da, kod tabanınızda sürüm geçmişi olması iyi bir uygulamadır ve bu dosyayı sürüm kontrol sisteminize kaydetmelisiniz (ancak uygulamanızla birlikte göndermeyin!).

Şemayı kontrol etmek gerekmez ve uyarı kurtulmak istiyorum Yani eğer sadece eklemek exportSchema = falseadresinden Müşteri RoomDatabaseolarak takip.

@Database(entities = { YourEntity.class }, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
   //...
}

Aşağıdaki @mikejonesguy cevabını takip ederseniz , dokümanlarda belirtilen iyi uygulamaları takip edersiniz :). Temelde klasörünüzde bir .jsondosya alırsınız ../app/schemas/. Ve şuna benziyor:

{
  "formatVersion": 1,
  "database": {
    "version": 1,
    "identityHash": "53db508c5248423325bd5393a1c88c03",
    "entities": [
      {
        "tableName": "sms_table",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` TEXT, `date` INTEGER, `client_id` INTEGER)",
        "fields": [
          {
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER"
          },
          {
            "fieldPath": "message",
            "columnName": "message",
            "affinity": "TEXT"
          },
          {
            "fieldPath": "date",
            "columnName": "date",
            "affinity": "INTEGER"
          },
          {
            "fieldPath": "clientId",
            "columnName": "client_id",
            "affinity": "INTEGER"
          }
        ],
        "primaryKey": {
          "columnNames": [
            "id"
          ],
          "autoGenerate": true
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"53db508c5248423325bd5393a1c88c03\")"
    ]
  }
}

Anlayışım doğruysa, her veritabanı sürümü güncellemesiyle böyle bir dosya alacaksınız, böylece db'nizin geçmişini kolayca takip edebilirsiniz.


8
Gerçekten "Uygulamanızla birlikte gönderme" ne anlama geliyor? APK'ya dahil olacak mı?
Jongz Puangput

2
"Uygulamanızla birlikte gönderme" seçeneğini izlerseniz, APK oluşturmadan önce JSON dosyalarını kaldırmalı mıyım?
illusionJJ

8
"Uygulamanızla birlikte gönderme", "schemaLocation uygulamasını 'app / res / raw' olarak ayarlamayın. SchemaLocation'ı APK'da bulunmayan bir dizine ayarlayın."
galcyurio

3
@ galcyurio $ projectDir / şemaları APK dışındaki bir dizin, değil mi? Oluşturulan APK'yi keşfettim ve orada görmüyorum. Ben / res (app / src / main / res için hangi hesapları) görmek rağmen.
xarlymg89

1
@glucaio APK'yı (ve Uygulama paketini de) keşfettim ve bulamadım. Bu yüzden güvende olduğumuza inanıyorum.
xarlymg89

390

In build.gradleuygulama modülü için dosyaya bu eklenti defaultConfig(altında bölüm androidbölüm). Bu, şemayı schemasproje klasörünüzün bir alt klasörüne yazar.

javaCompileOptions {
    annotationProcessorOptions {
        arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
    }
}

Bunun gibi:

// ...

android {

    // ... (compileSdkVersion, buildToolsVersion, etc)

    defaultConfig {

        // ... (applicationId, miSdkVersion, etc)

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }

    // ... (buildTypes, compileOptions, etc)

}

// ...

35
Herkes merak ediyorsa, bu kesin yaklaşım kapt
DanielDiSu

1
app/schemasBu işlemle dizinde oluşturulan json dosyasını gitignore etmeliyiz . Şemayı, içinde bulunmayan bir dizine koymamız gerektiğini duydum apk. Bunu nasıl yapabiliriz?
ravi

2
@ravi, oluşturulan şema dosya (lar) ı, değişiklikleri saptamak ve veritabanı değişikliklerinin veritabanı sürümünü güncellediğinizden ve bir geçiş planı oluşturduğunuzdan emin olmak için Room tarafından kullanıldığı için sürüm kontrolünde saklanmalıdır
appmattus 7'de

1
Bu yapılandırma sürüm sürümünü etkiler mi? Yani, projeyi bir yayın uygulamasına aktardığımda.
Anargu

Bu çözüm HATA ile sonuçlanırsa : Bağımsız değişkenler için yöntem ek açıklamasıProcessorOptions () bulunamadı , aşağıda Luna'nın yanıtına bakın: stackoverflow.com/a/54366985/1617737
ban-geoengineering

185

Kotlin? İşte başlıyoruz:

android {

    // ... (compileSdkVersion, buildToolsVersion, etc)

    defaultConfig {

        // ... (applicationId, miSdkVersion, etc)

        kapt {
            arguments {
                arg("room.schemaLocation", "$projectDir/schemas")
            }
        }
    }

    buildTypes {
        // ... (buildTypes, compileOptions, etc)
    }
}

//...

Eklentiyi unutmayın:

apply plugin: 'kotlin-kapt'

Kotlin not işlemcisi hakkında daha fazla bilgi için lütfen şu adresi ziyaret edin: Kotlin docs


Yanıtınız gibi: D
theapache64

12

Yukarıdaki cevaplar doğrudur. Bu sürümü takip etmek kolaydır:

"Şema dışa aktarma dizini ek açıklama işlemcisine sağlanmadığından", bu nedenle şema dışa aktarma için dizini sağlamalıyız:

Adım [1] RoomDatabase'i genişleten dosyanızda, satırı şu şekilde değiştirin:

`@Database(entities = ???.class,version = 1, exportSchema = true)`

Veya

`@Database(entities = ???.class,version = 1)` 

(çünkü varsayılan değer her zaman doğrudur)

Adım [2] build.gradle (project: ????) dosyanızda, defaultConfig {} ( android {} büyük bölümünde) içinde javaCompileOptions {} bölümünü ekleyin, şöyle olacaktır:

         android{
                defaultConfig{
                      //javaComplieOptions SECTION
                      javaCompileOptions {
                            annotationProcessorOptions {
                                     arguments = ["room.schemaLocation":"$projectDir/schemas".toString()]
                            }
                       }
                      //Other SECTION
                      ...
                }
         }

$ projectDir : değişken bir isimdir, değiştiremezsiniz. kendi proje dizininizi alacak

schemas : bir dizedir, istediğiniz gibi değiştirebilirsiniz. Örneğin: "$projectDir/MyOwnSchemas".toString()


adım [2] 'de olduğundan emin build.gradle(project:????)değil build.gradle(app:????)misiniz?
Ace

9

@mikejonesguy yanıtı mükemmeldir, sadece oda geçişlerini test etmeyi planlıyorsanız (önerilen), şema konumunu kaynak kümelerine ekleyin.

Build.gradle dosyanızda, oluşturulan bu şema JSON dosyalarını yerleştirmek için bir klasör belirtirsiniz. Şemanızı güncelledikçe, her sürüm için bir tane olmak üzere birkaç JSON dosyası elde edersiniz. Oluşturulan her dosyayı kaynak denetimine verdiğinizden emin olun. Sürüm numaranızı bir sonraki sefer yükselttiğinizde Room, test için JSON dosyasını kullanabilecektir.

  • Florina Muntenescu ( kaynak )

build.gradle

android {

    // [...]

    defaultConfig {

        // [...]

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }

    // add the schema location to the source sets
    // used by Room, to test migrations
    sourceSets {
        androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
    }

    // [...]
}

3

.ktsGradle dosyalarını (Kotlin Gradle DSL) ve kotlin-kapteklentiyi kullanıyorum, ancak Ivanov Maksim'in cevabını kullandığımda hala bir komut dosyası derleme hatası alıyorum.

Unresolved reference: kapt

Benim için çalışan tek şey buydu:

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = mapOf("room.schemaLocation" to "$projectDir/schemas")
            }
        }
    }
}

Benim için de hiçbir şey çalışmıyor. Kotlin kullanıyorum.
nyxee

0

Muhtemelen oda sınıfınızı çocuk RoomDatabaseçocuk sınıfına eklemediniz.@Database(entities = {your_classes})

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.