Получение `неправильно разделенного кортежа в операторе вставки с одним разделом` при попытке вставить данные в разделенную таблицу с помощью`TABLE_NAME.insert`
Я создаю таблицу 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)
Я нашел найденную ссылку ( 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;
А ТАКЖЕ
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 ответ
Процедура "EMPLOYEE.insert" - это то, что называется процедурой "по умолчанию", которая автоматически генерируется VoltDB при создании таблицы EMPLOYEE. Он уже автоматически разделен на основе разделения таблицы, поэтому вы не можете вызвать "PARTITION PROCEDURE EMPLOYEE.insert ...", чтобы переопределить это.
Я думаю, что происходит, что процедура разделена на столбец ID, который в таблице EMPLOYEE является VARCHAR. Поэтому входной параметр должен быть строкой. Тем не менее, я думаю, что ваш код каким-то образом читает файл CSV и передает в первом столбце значение int.
Метод java-клиента callProcedure(String methodName, Object... params) принимает переменные для параметров. Это может быть любой объект []. По пути где-то на сервере выполняется проверка, где # аргументов должно соответствовать # ожидаемому процедурой, иначе вызов процедуры возвращается как отклоненный, и он никогда бы не был выполнен. Тем не менее, я думаю, что в вашем случае количество аргументов в порядке, поэтому он пытается выполнить процедуру. Он хэширует 1-е значение параметра, соответствующее ID, а затем определяет, к какому разделу он должен перейти. Вызов направляется в этот раздел для выполнения. Когда он выполняется, он пытается вставить значения, но есть еще одна проверка, что значение ключа раздела является правильным для этого раздела, и это не удается.
Я думаю, что если значение передается как int, оно хэшируется в неправильный раздел. Затем в этом разделе он пытается вставить значение в столбец, который является VARCHAR, поэтому он, вероятно, неявно преобразует int в String, но он не находится в правильном разделе, поэтому вставка завершается неудачно с этой ошибкой. оператор вставки раздела. " что является той же ошибкой, которую вы получили бы, если бы вы написали хранимую процедуру Java и настроили неправильный столбец в качестве ключа раздела.
Раскрытие информации: я работаю в VoltDB.