- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的问题:我正在转换现有的 Java 桌面应用程序,并且正在学习 Android Room 开发,并通过 SQLite Studio 创建了一个预填充的 SQLite 数据库,其中包含多对多联接表(即 Author_By_Source)。该数据库和表用于现有的 Java 桌面应用程序。我正在尝试解决“notNull”和“primaryKeyPosition”属性之间的无效架构不匹配问题。我无法更新这两个属性。这是我尝试解决 AuthorID 字段的错误部分,但同一错误消息中的 SourceID 也存在相同的差异。因此这两个字段需要相同的分辨率:
Expected:
TableInfo{name='Author_By_Source', columns={AuthorID=Column{name='AuthorID', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}, ...
Found:
TableInfo{name='Author_By_Source', columns={AuthorID=Column{name='AuthorID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0, defaultValue='null'}, ...
我尝试过的:我尝试使用 SQLite Studio 界面来构建和构建数据库,并编辑“Author_By_Source”表的表结构。我将每个字段设置为“Not Null”,但当我重新运行应用程序时,它不会反射(reflect)为“true”。我还没有确定如何指定primaryKeyPosition。我尝试了相反的方法,更彻底地阅读房间注释的选项和方法,但没有成功。我在整个项目中阅读了一些 Room 文档,并访问了一些论坛和教程,但没有找到任何解决这一具体问题的内容。
我正在尝试做什么:我正在尝试使用包含多个表的预填充数据库,其中一些表具有用于多对多关系的连接表。我希望能得到一些指导。
下面是我如何注释我的 AuthorBySource 类,这可能会有所帮助:
@Entity(tableName = "Author_By_Source", primaryKeys = {"AuthorID", "SourceID"}, foreignKeys = {
@ForeignKey(entity = Authors.class, parentColumns = "AuthorID", childColumns = "AuthorID"),
@ForeignKey(entity = Sources.class, parentColumns = "SourceID", childColumns = "SourceID")},
indices = {@Index("AuthorID"), @Index("SourceID")})
public class AuthorBySource {
@ColumnInfo(name = "AuthorID")
private int authorID;
@ColumnInfo(name = "SourceID")
private int sourceID;
最佳答案
每次进行更改时,您是否都会重新复制 Assets 文件并卸载应用程序?如果没有并且这不能解决问题,那么:-
如果您编译房间代码,请查看 your_database_class_impl 中的 java(生成)(其中 your_database_class 是您的 @Database 类名称)和方法 createAllTables。其中有用于创建数据库的 SQL(您可以忽略 room_master SQL)。
例如(这基于您的实体和最小引用表):-
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `Authors` (`AuthorID` INTEGER, `AuthorName` TEXT, PRIMARY KEY(`AuthorID`))");
_db.execSQL("CREATE TABLE IF NOT EXISTS `Sources` (`SourceID` INTEGER, `SourceName` TEXT, PRIMARY KEY(`SourceID`))");
_db.execSQL("CREATE TABLE IF NOT EXISTS `Author_By_Source` (`AuthorID` INTEGER NOT NULL, `SourceID` INTEGER NOT NULL, PRIMARY KEY(`AuthorID`, `SourceID`), FOREIGN KEY(`AuthorID`) REFERENCES `Authors`(`AuthorID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`SourceID`) REFERENCES `Sources`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION )");
_db.execSQL("CREATE INDEX IF NOT EXISTS `index_Author_By_Source_AuthorID` ON `Author_By_Source` (`AuthorID`)");
_db.execSQL("CREATE INDEX IF NOT EXISTS `index_Author_By_Source_SourceID` ON `Author_By_Source` (`SourceID`)");
_db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
_db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '953f8512db886fb7d206fa561a7117c4')");
}
您需要相应地转换数据库,即按照定义,因此例如您可以在 SQLite Studio 中使用上述内容
/* Just once */
PRAGMA foreign_keys = 0;
/* Per table */
DROP TABLE IF EXISTS Author_By_Source_new;
DROP TABLE IF EXISTS Author_By_Source_original;
CREATE TABLE IF NOT EXISTS Author_By_Source_new copy_generated_sql_for_the_column_definitions_etc;
DELETE FROM Author_By_Source_new;
INSERT INTO Author_By_Source_new SELECT * FROM Author_By_Source;
ALTER TABLE Author_By_Source RENAME TO Author_By_Source_original;
ALTER TABLE Author_By_Source_new RENAME TO Author_By_Source;
/* IF HAPPY THEN DO */
-- DROP TABLE IF EXISTS Author_By_Source_original; /* NOTE TURNED OFF */
...... do the equivalent for all tables
/* Just once */
PRAGMA foreign_keys = 1;
PRAGMA foreign_key_check;
PRAGMA integrity_check;
INSERT INTO ....
语句假定新表和原始表的列顺序相同,否则使用 INSERT INTO (column_list)....
其中列是根据生成的 SQL 例如INSERT INTO Author_By_Source_new (AuthorID,SourceID) SELECT * FROM Author_By_Source;
CREATE TABLE SQL 将是(基于上面生成的 SQL)
CREATE TABLE IF NOT EXISTS `Author_By_Source_new` (`AuthorID` INTEGER NOT NULL, `SourceID` INTEGER NOT NULL, PRIMARY KEY(`AuthorID`, `SourceID`), FOREIGN KEY(`AuthorID`) REFERENCES `Authors`(`AuthorID`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`SourceID`) REFERENCES `Sources`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION );
这是一个基于您的代码中可用内容的示例。
数据库是使用 SQLite 管理工具 (Navicat) 生成的:-
DROP TABLE IF EXISTS Author_By_Source;
DROP TABLE IF EXISTS Authors;
DROP TABLE IF EXISTS Sources;
CREATE TABLE IF NOT EXISTS Authors (AuthorID INTEGER PRIMARY KEY, AuthorName TEXT);
CREATE TABLE IF NOT EXISTS Sources (SourceID INTEGER PRIMARY KEY, SourceName TEXT);
/* Create the table so that it would cause issues in Room */
CREATE TABLE IF NOT EXISTS Author_By_Source (
AuthorId INTEGER, SourceId INTEGER,
FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID),
FOREIGN KEY (SourceID) REFERENCES Sources(SourceID)
);
INSERT INTO Authors (AuthorName) VALUES ('Fred'),('Mary'),('Joan'),('Bert'),('Alan');
INSERT INTO Sources (SourceName) VALUES ('S1'),('S2'),('S3'),('S4'),('S5');
INSERT INTO Author_By_Source VALUES(1,1),(2,2),(3,3),(4,4),(5,5),(1,4),(3,4),(5,2);
SELECT AuthorName, SourceName
FROM Author_By_Source
JOIN Authors ON Author_By_Source.AuthorID = Authors.AuthorID
JOIN Sources ON Author_By_Source.SourceID = Sources.SourceID
;
运行后:-
AuthorName SourceName
Fred S1
Mary S2
Joan S3
Bert S4
Alan S5
Fred S4
Joan S4
Alan S2
正如预期的那样,尝试使用此结果:-
java.lang.RuntimeException: Unable to start activity ComponentInfo{a.a.so59756782javaroomprepopulatedconversion/a.a.so59756782javaroomprepopulatedconversion.MainActivity}: java.lang.IllegalStateException: Pre-packaged database has an invalid schema: Authors(a.a.so59756782javaroomprepopulatedconversion.Authors).
Expected:
TableInfo{name='Authors', columns={AuthorName=Column{name='AuthorName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}, AuthorID=Column{name='AuthorID', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=1, defaultValue='null'}}, foreignKeys=[], indices=[]}
Found:
TableInfo{name='Authors', columns={AuthorID=Column{name='AuthorID', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=1, defaultValue='null'}, AuthorName=Column{name='AuthorName', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0, defaultValue='null'}}, foreignKeys=[], indices=[]}
根据答案,以下内容用于转换数据库:-
BEGIN TRANSACTION;
DROP TABLE IF EXISTS Author_By_Source;
DROP TABLE IF EXISTS Authors;
DROP TABLE IF EXISTS Sources;
CREATE TABLE IF NOT EXISTS `Authors` (`AuthorID` INTEGER NOT NULL, `AuthorName` TEXT, PRIMARY KEY(`AuthorID`));
CREATE TABLE IF NOT EXISTS `Sources` (`SourceID` INTEGER NOT NULL, `SourceName` TEXT, PRIMARY KEY(`SourceID`));
/* Create the table so that it would cause issues in Room */
CREATE TABLE IF NOT EXISTS Author_By_Source (
AuthorId INTEGER, SourceId INTEGER,
FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID),
FOREIGN KEY (SourceID) REFERENCES Sources(SourceID)
);
INSERT INTO Authors (AuthorName) VALUES ('Fred'),('Mary'),('Joan'),('Bert'),('Alan');
INSERT INTO Sources (SourceName) VALUES ('S1'),('S2'),('S3'),('S4'),('S5');
INSERT INTO Author_By_Source VALUES(1,1),(2,2),(3,3),(4,4),(5,5),(1,4),(3,4),(5,2);
SELECT AuthorName, SourceName
FROM Author_By_Source
JOIN Authors ON Author_By_Source.AuthorID = Authors.AuthorID
JOIN Sources ON Author_By_Source.SourceID = Sources.SourceID
;
/* Just once */
PRAGMA foreign_keys = 0;
/* Per table */
DROP TABLE IF EXISTS Author_By_Source_new;
DROP TABLE IF EXISTS Author_By_Source_original;
CREATE TABLE IF NOT EXISTS `Author_By_Source_new`
(
`AuthorID` INTEGER NOT NULL,
`SourceID` INTEGER NOT NULL,
PRIMARY KEY(`AuthorID`, `SourceID`),
FOREIGN KEY(`AuthorID`) REFERENCES `Authors`(`AuthorID`) ON UPDATE NO ACTION ON DELETE NO ACTION ,
FOREIGN KEY(`SourceID`) REFERENCES `Sources`(`SourceID`) ON UPDATE NO ACTION ON DELETE NO ACTION
);
DELETE FROM Author_By_Source_new;
INSERT INTO Author_By_Source_new SELECT * FROM Author_By_Source;
ALTER TABLE Author_By_Source RENAME TO Author_By_Source_original;
ALTER TABLE Author_By_Source_new RENAME TO Author_By_Source;
/* IF HAPPY THEN DO */
DROP TABLE IF EXISTS Author_By_Source_original;
-- ...... do the equivalent for all tables
CREATE INDEX IF NOT EXISTS `index_Author_By_Source_SourceID` ON `Author_By_Source` (`SourceID`);
CREATE INDEX IF NOT EXISTS `index_Author_By_Source_AuthorID` ON `Author_By_Source` (`AuthorID`);
COMMIT;
/* Just once */
PRAGMA foreign_keys = 1;
PRAGMA foreign_key_check;
PRAGMA integrity_check;
SELECT sql FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite%';
SELECT AuthorName, SourceName
FROM Author_By_Source
JOIN Authors ON Author_By_Source.AuthorID = Authors.AuthorID
JOIN Sources ON Author_By_Source.SourceID = Sources.SourceID
;
数据库已关闭,检查时间戳和大小,然后数据库文件替换 Assets 文件夹中的现有文件。该应用程序已卸载,然后在 MainActivity 中使用以下内容重新运行:-
myDB = Room.databaseBuilder(this,MyAppDatabase.class,"mydb")
.createFromAsset("mydb")
.allowMainThreadQueries()
.build();
myDB.getOpenHelper().getWritableDatabase();
List<AuthorWithSources> authorWithSourcesList = myDB.allDao().getAllAuthorsWithSources();
for (AuthorWithSources aws: authorWithSourcesList) {
Log.d("AUTHORSOURCEINFO","Author = " + aws.authors.getAuthorName() + "Source = " + aws.sources.getSourceName());
}
}
myDB.getOpenHelper().getWritableDatabase();
用于强制立即打开数据库并因此复制数据库。
getAllAuthorsWithSources()
正如它所说,使用
@Query("SELECT * FROM Author_By_Source")
List<AuthorWithSources> getAllAuthorsWithSources();
AuthorWithSources 是:-
public class AuthorWithSources {
@Embedded
AuthorBySource authorBySource;
@Relation(entity = Authors.class,parentColumn = "AuthorID",entityColumn = "AuthorID")
Authors authors;
@Relation(entity = Sources.class,parentColumn = "SourceID",entityColumn = "SourceID")
Sources sources;
}
没有错误并且在日志中:-
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = FredSource = S1
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = MarySource = S2
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = JoanSource = S3
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = BertSource = S4
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = AlanSource = S5
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = FredSource = S4
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = JoanSource = S4
2020-01-16 10:09:23.623 D/AUTHORSOURCEINFO: Author = AlanSource = S2
有一个工具,作为一个应用程序,可以转换数据库以供 Room 使用,并为实体/Dao 生成 java 代码。
该工具的详细信息请参见 RoomExistingSQLiteDBConverter
使用该工具和
最后创建代码来使用数据库,例如
soanswersDatabase = Room.databaseBuilder(this,SoanswersDatabase.class,SoanswersDatabase.DBNAME)
.allowMainThreadQueries()
.createFromAsset(SoanswersDatabase.DBNAME)
.build();
List<Author_By_Source> authorBySourceList = soanswersDatabase.getAuthor_By_SourceDao().getEveryAuthor_By_Source();
for (Author_By_Source abs: authorBySourceList) {
Log.d("AUTHORSOURCEINFO",
"AuthorReference = " + String.valueOf(abs.getAuthorId())
+ " Sourcereference = " + String.valueOf(abs.getSourceId())
);
}
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 1 Sourcereference = 1
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 2 Sourcereference = 2
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 3 Sourcereference = 3
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 4 Sourcereference = 4
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 5 Sourcereference = 5
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 1 Sourcereference = 4
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 3 Sourcereference = 4
2020-01-16 10:46:27.907 D/AUTHORSOURCEINFO: AuthorReference = 5 Sourcereference = 2
关于java - 如何解决预填充数据库上涉及 'notNull' 和 'primaryKeyPosition' 的 Room 无效架构错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59756782/
我正在阅读哈德利的 Advanced R并尝试一些东西。我正在尝试创建一个 lazy闭包函数返回一个带有提供的函数 data.frame在其环境中以及使用 with并且能够在以后提供额外的函数参数。
我有两个 ViewController。初始 ViewController 是输入和存储 URL 的地方。此初始 ViewController 的 viewDidLoad 还应该在应用程序启动时开始加
你是怎么用的 对于应用程序中的 ListView 项也应该在设备 <11 上运行? 由于 activated_state 在 HC 之前不可用,我只能想到两个肮脏的解决方法: 在您的 Activit
我正在为 android (2.1 > 3.1) 编写一个应用程序,我想使用熟悉的做法,即在 Honeycomb 应用程序中使用应用程序图标来进入家庭 Activity ,但是,当我之前运行该 Act
如果搜索的键不存在,我如何覆盖方法 GET 或编写一个将在服务器端执行的新函数返回另一个键值? 示例: 如果关键字“word_1 word_2 word_3 word_4”不存在则搜索关键字“word
对于我的存储库,我使用的是 Git 和 Stash。在 Stash 端,我限制了(只读)对 master 的访问权限,因此任何用户都可以从 master 分支分支以获取功能/分支,但不能直接 merg
如何配置dgrid及其存储以定义渲染行时是否已经选择了行? 例如,如果我的行数据是这样的: { id: 1, name: 'Item Name', selected: true } 我当前
有没有一种方法可以将变量从一个 BeanShell 前/后处理器引用到另一个 BeanShell 处理器(它们在同一个线程组中)? 如果我在 HTTP 请求下的 BeanShell 预处理器中创建了一
问题 我已尝试添加预操作 shell 脚本,这些脚本会根据我正在构建的内容打开/关闭我的 .pch 文件中的某些定义。 但是,在运行构建时,没有任何反应。我不是一个流利的 shell 脚本编写者,所以
我有一个 HTML 字符串用作 jQuery 输入文档。 // the variable html contains the HTML code jQuery( html ).find( 'p' ).
在 Mercurial 中允许 merge 之前有没有办法进行一些检查? 通过将以下内容添加到 ~/.hg/hgrc,我找到了更新前 Hook ,并拥有一个在允许更新之前运行的脚本: [hooks]
总结: 预 Controller Hook 是否在缓存期间执行?是否有任何 Hook 点可以执行? (系统前?) 我应该强调一个事实,即 Hook 不会影响发送到浏览器的内容。这不是问题。 详细版:
我正在使用适用于 android 的 Skobbler Map API,到目前为止它一直非常好。按照官方的“操作方法”,我已经能够将 map 应用到我的应用程序中。比我可以让应用程序下载 map 并离
当我安装bcrypt时我的 hapi js 项目的模块尚未安装,它显示类似 node-pre-gyp install --fallback-to-build 我尝试通过运行来安装; npm i nod
我试图使用此代码的变体: apply plugin: 'java' apply plugin: 'idea' idea.workspace.iws.withXml { provider ->
假设我们有一个 PHP 项目,其依赖项 A 和 B 分别依赖于 PHP 库 X,但版本不同。 通常,人们会使用诸如 composer 之类的 PHP 依赖管理器,它可以通过在与 A 和 B 兼容的版本
这似乎违背了代码块的目的,但我希望能够在代码块中加粗。例如,如果我想将返回行加粗: int main(void) { **return 0;** } 最佳答案 您必须在 HTML 中执行此操作
我们是否应该使用 Huggingface(预)训练一个 BERT 无框模型的小写输入数据?我查看了 Thomas Wolf ( https://github.com/huggingface/trans
我有两个模式: 技能: var mongoose = require("mongoose"); var SkillSchema = new mongoose.Schema({ skill: {
我这里有问题。这适用于 Chrome,但我无法在 IE11 的 index.html 中使用任何动画。当它不想工作时,我会看到一个静态屏幕。同样在 IE 中,消息不会像它应该的那样消失。如果我将 di
我是一名优秀的程序员,十分优秀!