![](/img/trans.png)
[英]Play Anorm insert a scala List into a postgres text array column
[英]Anorm string set from postgres ltree column
我有一個表,其中一列具有ltree類型,以下代碼從中獲取數據:
SQL("""select * from "queue"""")()
.map(
row =>
{
val queue =
Queue(
row[String]("path"),
row[String]("email_recipients"),
new DateTime(row[java.util.Date]("created_at")),
row[Boolean]("template_required")
)
queue
}
).toList
這會導致以下錯誤:
RuntimeException: TypeDoesNotMatch(Cannot convert notification.en.incident_happened:class org.postgresql.util.PGobject to String for column ColumnName(queue.path,Some(path)))
隊列表模式如下:
CREATE TABLE queue
(
id serial NOT NULL,
template_id integer,
template_version integer,
path ltree NOT NULL,
json_params text,
email_recipients character varying(1024) NOT NULL,
email_from character varying(128),
email_subject character varying(512),
created_at timestamp with time zone NOT NULL,
sent_at timestamp with time zone,
failed_recipients character varying(1024),
template_required boolean NOT NULL DEFAULT true,
attachments hstore,
CONSTRAINT pk_queue PRIMARY KEY (id ),
CONSTRAINT fk_queue__email_template FOREIGN KEY (template_id)
REFERENCES email_template (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE RESTRICT
)
WITH (
OIDS=FALSE
);
ALTER TABLE queue
OWNER TO postgres;
GRANT ALL ON TABLE queue TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE queue TO writer;
GRANT SELECT ON TABLE queue TO reader;
這是為什么? 不是notification.en.incident_happened
只是一個普通的字符串? 或者我錯過了什么?
UPD :
這個問題仍然適用,但這是一個解決方法:
SQL("""select id, path::varchar, email_recipients, created_at, template_required from "queue"""")()
這看起來像一個有趣的項目,所以我實現了ltree列映射器。
我捎帶了anorm-postgresql ,因為該項目已經在anorm中實現了一些postgres類型。 它看起來不錯,如果它實現了全系列的postgres類型,它會很有用。 我的代碼已合並,因此您可以使用該庫。 或者,只需使用以下代碼:
import org.postgresql.util.PGobject
import anorm._
object LTree {
implicit def rowToStringSeq: Column[Seq[String]] = Column.nonNull { (value, meta) =>
val MetaDataItem(qualified, nullable, clazz) = meta
value match {
case pgo:PGobject => {
val seq = pgo.getValue().split('.')
Right(seq.toSeq)
}
case x => Left(TypeDoesNotMatch(x.getClass.toString))
}
}
implicit def stringSeqToStatement = new ToStatement[Seq[String]] {
def set(s: java.sql.PreparedStatement, index: Int, aValue: Seq[String]) {
val stringRepresentation = aValue.mkString(".")
val pgo:org.postgresql.util.PGobject = new org.postgresql.util.PGobject()
pgo.setType("ltree");
pgo.setValue( stringRepresentation );
s.setObject(index, pgo)
}
}
}
然后,您可以將ltree
映射到Seq[String]
。 請注意,它是一系列路徑元素的順序,所以它是一個Seq[String]
,而不是String
或Set[String]
。 如果你想要一個字符串,只需說出path.mkString(".")
。 用法如下:
import LTree._
SQL("""select * from "queue"""")()
.map(
row =>
{
val queue =
Queue(
row[Seq[String]]("path"),
row[String]("email_recipients"),
new DateTime(row[java.util.Date]("created_at")),
row[Boolean]("template_required")
)
queue
}
).toList
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.