MySQL join tables with Kotlin Exposed error: "no matching primary/foreign key pair"
MySQL join tables with Kotlin Exposed error: "no matching primary/foreign key pair"
我正在使用 Exposed 库在 Kotlin 中处理遗留 MySQL 数据库。我已经让它在 MySQL 下正常工作(简单查询按预期工作)。我是运行MySQL版本5.7.26,但我认为问题与MySQL本身无关。
我有两个表,events 和 event_years。事件中的相关列是 id(int,主键)和名称(varchar 255)。 Event_years 包含一个 id(int,主键),year(日期时间)和 event_id(int,外键),以及与此问题无关的其他内容。
一个事件在 event_years 中可能有零行或多行引用它。我想 select 事件名称和年份,并按年份对结果进行排序。
我可以像这样使用 mysql CLI 实现此目的:
SELECT e.id, e.name, y.id, y.date
FROM events e, event_years y
WHERE e.id = y.event_id
ORDER BY y.date;
在 Kotlin 中,我为 Events 和 EventYears 创建了对象:
object Events : Table("events") {
val id = integer("id").autoIncrement().primaryKey()
val name = varchar("name", length = 255)
}
object EventYears : Table("event_years") {
val id = integer("id").autoIncrement().primaryKey()
val eventId = integer("event_id").uniqueIndex()
val date = date("date")
}
然后我尝试了以下查询:
val res = EventYears.innerJoin(Events)
.slice(Events.name, Events.id, EventYears.date, EventYears.id)
.select { EventYears.eventId eq Events.id }
.groupBy(EventYears.date)
我希望结果是一个包含这些值的 Iterable 对象(就像我在没有连接的情况下进行查询时收到的那些),但是出现了异常:
java.lang.IllegalStateException: Cannot join with foo.bar.Events@b307e119 as there is no matching primary key/ foreign key pair and constraint missing
提前感谢您的帮助。我已经阅读了两次 Exposed 文档,但仍然不明白为什么这不起作用。
尝试指定约束:
val joinResult = Events.join(EventYears, JoinType.INNER, additionalConstraint = {
EventYears.eventId eq Events.id
然后select如下
joinResult.select({ EventYears.eventId eq Events.id }) {
val eventId = it[Events.id]
val eventYearsId = it[EventYears.eventId]
}
您应该将 eventId
定义为 val eventId = reference("film", Events).uniqueIndex()
,然后您就可以毫无例外地使用您的查询。
另一种方法是在 innerJoin
中明确提供两列
val res = EventYears.innerJoin(Events, {EventYears.eventId}, {Events.id})
.slice(Events.name, Events.id, EventYears.date, EventYears.id)
.selectAll()
.groupBy(EventYears.date)
我正在使用 Exposed 库在 Kotlin 中处理遗留 MySQL 数据库。我已经让它在 MySQL 下正常工作(简单查询按预期工作)。我是运行MySQL版本5.7.26,但我认为问题与MySQL本身无关。
我有两个表,events 和 event_years。事件中的相关列是 id(int,主键)和名称(varchar 255)。 Event_years 包含一个 id(int,主键),year(日期时间)和 event_id(int,外键),以及与此问题无关的其他内容。
一个事件在 event_years 中可能有零行或多行引用它。我想 select 事件名称和年份,并按年份对结果进行排序。
我可以像这样使用 mysql CLI 实现此目的:
SELECT e.id, e.name, y.id, y.date
FROM events e, event_years y
WHERE e.id = y.event_id
ORDER BY y.date;
在 Kotlin 中,我为 Events 和 EventYears 创建了对象:
object Events : Table("events") {
val id = integer("id").autoIncrement().primaryKey()
val name = varchar("name", length = 255)
}
object EventYears : Table("event_years") {
val id = integer("id").autoIncrement().primaryKey()
val eventId = integer("event_id").uniqueIndex()
val date = date("date")
}
然后我尝试了以下查询:
val res = EventYears.innerJoin(Events)
.slice(Events.name, Events.id, EventYears.date, EventYears.id)
.select { EventYears.eventId eq Events.id }
.groupBy(EventYears.date)
我希望结果是一个包含这些值的 Iterable 对象(就像我在没有连接的情况下进行查询时收到的那些),但是出现了异常:
java.lang.IllegalStateException: Cannot join with foo.bar.Events@b307e119 as there is no matching primary key/ foreign key pair and constraint missing
提前感谢您的帮助。我已经阅读了两次 Exposed 文档,但仍然不明白为什么这不起作用。
尝试指定约束:
val joinResult = Events.join(EventYears, JoinType.INNER, additionalConstraint = {
EventYears.eventId eq Events.id
然后select如下
joinResult.select({ EventYears.eventId eq Events.id }) {
val eventId = it[Events.id]
val eventYearsId = it[EventYears.eventId]
}
您应该将 eventId
定义为 val eventId = reference("film", Events).uniqueIndex()
,然后您就可以毫无例外地使用您的查询。
另一种方法是在 innerJoin
val res = EventYears.innerJoin(Events, {EventYears.eventId}, {Events.id})
.slice(Events.name, Events.id, EventYears.date, EventYears.id)
.selectAll()
.groupBy(EventYears.date)