Получение `неправильно разделенного кортежа в операторе вставки с одним разделом` при попытке вставить данные в разделенную таблицу с помощью` TABLE_NAME.insert` - PullRequest
0 голосов
/ 24 января 2019

Я создаю таблицу VoltDB с заданным оператором вставки

CREATE TABLE EMPLOYEE (
    ID VARCHAR(4) NOT NULL,
    CODE VARCHAR(4) NOT NULL,
    FIRST_NAME VARCHAR(30) NOT NULL,
    LAST_NAME VARCHAR(30) NOT NULL,
    PRIMARY KEY (ID, CODE)
);

И делю таблицу с помощью

PARTITION TABLE EMPLOYEE ON COLUMN ID;

Я написал одно искровое задание для вставки данных в VoltDB, яЯ использую ниже Scala-код для вставки записей в VoltDB, код работает хорошо, если мы не разбиваем таблицу

import org.voltdb._;
import org.voltdb.client._;
import scala.collection.JavaConverters._

val voltClient:Client = ClientFactory.createClient();
voltClient.createConnection("IP:PORT");

val empDf = spark.read.format("csv")
          .option("inferSchema", "true")
          .option("header", "true")
          .option("sep", ",")
          .load("/FileStore/tables/employee.csv")

// Code to convert scala seq to java varargs
def callProcedure(procName: String, parameters: Any*): ClientResponse =
    voltClient.callProcedure(procName, paramsToJavaObjects(parameters: _*): _*)

def paramsToJavaObjects(params: Any*) = params.map { param ⇒
    val value = param match {
      case None    ⇒ null
      case Some(v) ⇒ v
      case _       ⇒ param
    }
    value.asInstanceOf[AnyRef]
}

empDf.collect().foreach { row =>
  callProcedure("EMPLOYEE.insert", row.toSeq:_*);
}

Но я получаю ошибку ниже, если я разбиваю таблицу

Mispartitioned tuple in single-partition insert statement.
Constraint Type PARTITIONING, Table CatalogId EMPLOYEE
Relevant Tuples:
ID  CODE  FIRST_NAME  LAST_NAME 
--- ----- ----------- ----------
1   CD01  Naresh       "Joshi"
    at org.voltdb.client.ClientImpl.internalSyncCallProcedure(ClientImpl.java:485)
    at org.voltdb.client.ClientImpl.callProcedureWithClientTimeout(ClientImpl.java:324)
    at org.voltdb.client.ClientImpl.callProcedure(ClientImpl.java:260)
    at line4c569b049a9d4e51a3e8fda7cbb043de32.$read$$iw$$iw$$iw$$iw$$iw$$iw.callProcedure(command-3986740264398828:9)
    at line4c569b049a9d4e51a3e8fda7cbb043de40.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(command-3986740264399793:8)
    at line4c569b049a9d4e51a3e8fda7cbb043de40.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$anonfun$1.apply(command-3986740264399793:7)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)

Iнашел, нашел ссылку (https://forum.voltdb.com/forum/voltdb-discussions/building-voltdb-applications/1182-mispartitioned-tuple-in-single-partition-insert-statement), касающуюся проблемы и попытался разделить процедуру, используя следующий запрос

PARTITION PROCEDURE EMPLOYEE.insert ON TABLE EMPLOYEE COLUMN ID;

AND

PARTITION PROCEDURE EMPLOYEE.insert ON TABLE EMPLOYEE COLUMN ID [PARAMETER 0];

Но я получаю [Ad Hoc DDL Input]: VoltDB DDL Error: "Partition references an undefined procedure "EMPLOYEE.insert"" ошибкупри выполнении этого оператора.

Однако я могу вставить данные с помощью хранимой процедуры @AdHoc, но не могу выяснить проблему или решение для вышеуказанного сценария, где я использую EMPLOYEE.insertхранимая процедура для вставки данных в многораздельную таблицу.

1 Ответ

0 голосов
/ 24 января 2019

Процедура «EMPLOYEE.insert» - это то, что называется процедурой «по умолчанию», которая автоматически генерируется VoltDB при создании таблицы EMPLOYEE.Он уже автоматически разделен на основе разделения таблицы, поэтому вы не можете вызвать «PARTITION PROCEDURE EMPLOYEE.insert ...», чтобы переопределить это.

Я думаю, что происходит то, что процедура разделенаСтолбец ID, который в таблице EMPLOYEE является VARCHAR.Поэтому входной параметр должен быть строкой.Тем не менее, я думаю, что ваш код каким-то образом читает файл CSV и передает в первый столбец значение int.

Метод java-клиента callProcedure (String methodName, Object ... params) принимает значения varargs для параметров.Это может быть любой объект [].По пути где-то на сервере выполняется проверка, где # аргументов должно соответствовать # ожидаемому процедурой, иначе вызов процедуры возвращается как отклоненный, и он никогда бы не был выполнен.Тем не менее, я думаю, что в вашем случае количество аргументов в порядке, поэтому он пытается выполнить процедуру.Он хэширует 1-е значение параметра, соответствующее ID, а затем определяет, к какому разделу он должен перейти.Вызов направляется в этот раздел для выполнения.Когда он выполняется, он пытается вставить значения, но есть еще одна проверка, что значение ключа раздела является правильным для этого раздела, и это не удается.

Я думаю, что если значение передается как int, оно хэшируется в неправильный раздел.Затем в этом разделе он пытается вставить значение в столбец, который является VARCHAR, поэтому он, вероятно, неявно преобразует int в String, но он не находится в правильном разделе, поэтому вставка завершается неудачно с этой ошибкой.оператор вставки раздела. "это та же ошибка, что и в случае, если вы написали хранимую процедуру Java и настроили неверный столбец в качестве ключа раздела.

Раскрытие информации: я работаю в VoltDB.

...