2013-02-06 8 views
9

Mam tabeli z jednej z kolumn o typ ltree i następujący kod pobierania danych z niego:Anorm ciąg ustawiony z kolumny postgres 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 

co powoduje następujący błąd:

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

schematu tabeli kolejka jest następujący:

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; 

Dlaczego tak jest? Czy nie jest to zwykły ciąg znaków? Czy może czegoś brakuje?

UPD:

Pytanie nadal obowiązuje, ale tutaj jest obejście:

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

Jaki jest schemat tabeli 'Queue'? –

+0

@JasonWebb Zaktualizowano pytanie. – zapadlo

+1

Ten link może pomóc: http://stackoverflow.com/questions/20024357/how-to-get-values-from-postgres-with-anorm –

Odpowiedz

4

To wyglądało projektem zabawy więc realizowany program mapowania kolumny ltree.

Odłączyłem się od anorm-postgresql, ponieważ projekt ten implementuje już niektóre typy PostgreSQL w anormie. Wygląda dobrze i byłoby użyteczne, gdyby wdrożył pełen zakres typów postgresów. Mój kod został scalony, więc możesz użyć tej biblioteki. Alternatywnie, wystarczy użyć następującego kodu:

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

Następnie można mapować się ltree do Seq[String]. Zauważ, że kolejność elementów elementów ścieżki ma znaczenie, dlatego jest to Seq[String], a nie String lub. Jeśli chcesz pojedynczy ciąg, powiedz po prostu path.mkString("."). Użycie poniżej:

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 
Powiązane problemy