簡體   English   中英

從postgres ltree列設置的Anorm字符串

[英]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] ,而不是StringSet[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM