简体   繁体   English

从postgres ltree列设置的Anorm字符串

[英]Anorm string set from postgres ltree column

I have a table with one of the columns having ltree type, and the following code fetching data from it: 我有一个表,其中一列具有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

which results in the following error: 这会导致以下错误:

RuntimeException: TypeDoesNotMatch(Cannot convert notification.en.incident_happened:class org.postgresql.util.PGobject to String for column ColumnName(queue.path,Some(path)))

queue table schema is the following: 队列表模式如下:

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;

Why is that? 这是为什么? Isn't notification.en.incident_happened just an ordinary string? 不是notification.en.incident_happened只是一个普通的字符串? Or am I missing anything? 或者我错过了什么?

UPD : UPD

The question still applies, but here is a workaround: 这个问题仍然适用,但这是一个解决方法:

SQL("""select id, path::varchar, email_recipients, created_at, template_required from "queue"""")()

This looked like a fun project so I implemented the ltree column mapper. 这看起来像一个有趣的项目,所以我实现了ltree列映射器。

I piggybacked off anorm-postgresql , since that project already implements some postgres types in anorm. 我捎带了anorm-postgresql ,因为该项目已经在anorm中实现了一些postgres类型。 It looks good, and it would be useful if it implemented the full range of postgres types. 它看起来不错,如果它实现了全系列的postgres类型,它会很有用。 My code has been merged in, so you can use that library. 我的代码已合并,因此您可以使用该库。 Alternatively, just use the following code: 或者,只需使用以下代码:

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)
    }
  }
}

Then you can map an ltree to a Seq[String] . 然后,您可以将ltree映射到Seq[String] Notice that it is a sequence of path elements order matters so it is a Seq[String] , rather than String or Set[String] . 请注意,它是一系列路径元素的顺序,所以它是一个Seq[String] ,而不是StringSet[String] If you want a single string just say path.mkString(".") . 如果你想要一个字符串,只需说出path.mkString(".") Usage below: 用法如下:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM