sydneyhoran opened a new issue, #8372:
URL: https://github.com/apache/hudi/issues/8372

   **Describe the problem you faced**
   
   Using Deltastreamer to ingest Avro messages from Kafka topics 
(PostgresDebeziumAvroPayload) into S3 Hudi tables. When using 
CustomKeyGenerator for multiple RecordKeys and timebased PartitionPath, 
Deltastreamer throws an error on first run if the partitionPath doesn't include 
the datatype.
   
   Configs:
   ```
   hoodie.datasource.write.recordkey.field=id,_changed_at,_change_type
   hoodie.datasource.write.partitionpath.field=inserted_at
   
hoodie.datasource.write.keygenerator.class=org.apache.hudi.keygen.CustomKeyGenerator
   hoodie.deltastreamer.keygen.timebased.timestamp.type=EPOCHMILLISECONDS
   hoodie.deltastreamer.keygen.timebased.output.dateformat=yyyy/MM/dd
   hoodie.datasource.write.precombine.field=updated_at
   ```
   
   Error:
   ```
   Caused by: org.apache.hudi.exception.HoodieKeyException: Unable to find 
field names for partition path in proper format
   ```
   
   We found that the first job must be run with the datatype (i.e. 
`hoodie.datasource.write.partitionpath.field=inserted_at:TIMESTAMP`), and Hudi 
automatically sets `hoodie.datasource.write.partitionpath.field` with the 
extracted partition path as `inserted_at` (without the :TIMESTAMP). However, on 
the following run, when we pass `inserted_at:TIMESTAMP`, the job fails due to 
config conflict.
   
   ```
   Exception in thread "main" org.apache.hudi.exception.HoodieException: Config 
conflict(key current value existing value):
   PartitionPath: inserted_at:TIMESTAMP inserted_at
   ```
   
   The :TIMESTAMP must be removed for subsequent runs, but appears to be 
required for the first run. The expected behavior is to allow configs be the 
same for first run vs all future runs.
   
   Is there another config we can set that would be compatible for first run as 
well as future runs?
   
   **To Reproduce**
   
   Steps to reproduce the behavior:
   
   1. Run Deltastreamer for Debezium Avro payload messages from Kafka topic
   2. Set configs to use CustomKeyGenerator, multiple record keys, 
EPOCHMILLISECONDS formatted partition path (don't set :TIMESTAMP) for the first 
run
   3. HoodieKeyException is produced `Unable to find field names for partition 
path in proper format`
   4. Change config to 
`hoodie.datasource.write.partitionpath.field=inserted_at:TIMESTAMP`
   5. Job runs as expected
   6. Run the job again with the same config ^ (:TIMESTAMP)
   7. HoodieException `Config conflict` is produced
   8. Remove :TIMESTAMP from partitionpath config
   9. Job runs as expected
   
   **Expected behavior**
   
   Deltastreamer should recognize the PartitionPath column on the first run, 
and configs should be the same for all future runs. If datatype needs to be 
specified, it should be put into the `.hoodie/hoodie.properties` file as 
inserted_at:TIMESTAMP so there is no config conflict later.
   
   **Environment Description**
   
   * Hudi version : 0.14.0-SNAPSHOT
   
   * Spark version : 3.1
   
   * Hive version : N/A
   
   * Hadoop version : N/A
   
   * Storage (HDFS/S3/GCS..) : S3
   
   * Running on Docker? (yes/no) : both
   
   
   **Additional context**
   
   Add any other context about the problem here.
   
   **Stacktrace**
   
   **For first run without specifying :TIMESTAMP:**
   
   ```
   Caused by: org.apache.hudi.exception.HoodieKeyException: Unable to find 
field names for partition path in proper format
        at 
org.apache.hudi.keygen.CustomAvroKeyGenerator.getPartitionPath(CustomAvroKeyGenerator.java:78)
        at 
org.apache.hudi.keygen.CustomKeyGenerator.getPartitionPath(CustomKeyGenerator.java:83)
        at 
org.apache.hudi.keygen.BaseKeyGenerator.getKey(BaseKeyGenerator.java:69)
        at 
org.apache.hudi.utilities.deltastreamer.DeltaSync.lambda$fetchFromSource$ddc224fb$1(DeltaSync.java:618)
        at 
org.apache.spark.api.java.JavaPairRDD$.$anonfun$toScalaFunction$1(JavaPairRDD.scala:1070)
        at scala.collection.Iterator$$anon$10.next(Iterator.scala:461)
        at scala.collection.Iterator$SliceIterator.next(Iterator.scala:273)
        at scala.collection.Iterator.foreach(Iterator.scala:943)
        at scala.collection.Iterator.foreach$(Iterator.scala:943)
        at scala.collection.AbstractIterator.foreach(Iterator.scala:1431)
        at scala.collection.generic.Growable.$plus$plus$eq(Growable.scala:62)
        at scala.collection.generic.Growable.$plus$plus$eq$(Growable.scala:53)
        at 
scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:105)
        at 
scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:49)
        at scala.collection.TraversableOnce.to(TraversableOnce.scala:366)
        at scala.collection.TraversableOnce.to$(TraversableOnce.scala:364)
        at scala.collection.AbstractIterator.to(Iterator.scala:1431)
        at scala.collection.TraversableOnce.toBuffer(TraversableOnce.scala:358)
        at scala.collection.TraversableOnce.toBuffer$(TraversableOnce.scala:358)
        at scala.collection.AbstractIterator.toBuffer(Iterator.scala:1431)
        at scala.collection.TraversableOnce.toArray(TraversableOnce.scala:345)
        at scala.collection.TraversableOnce.toArray$(TraversableOnce.scala:339)
        at scala.collection.AbstractIterator.toArray(Iterator.scala:1431)
        at org.apache.spark.rdd.RDD.$anonfun$take$2(RDD.scala:1449)
        at 
org.apache.spark.SparkContext.$anonfun$runJob$5(SparkContext.scala:2244)
        at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
        at org.apache.spark.scheduler.Task.run(Task.scala:131)
        at 
org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:505)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1439)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:508)
        ... 3 more
   ```
   
   **For subsequent runs keeping :TIMESTAMP in the config:**
   
   ```
   KeyGenerator:        org.apache.hudi.keygen.CustomKeyGenerator       
org.apache.hudi.keygen.TimestampBasedKeyGenerator
   PartitionPath:       inserted_at:TIMESTAMP   inserted_at
        at 
org.apache.hudi.HoodieWriterUtils$.validateTableConfig(HoodieWriterUtils.scala:181)
        at 
org.apache.hudi.HoodieWriterUtils$.validateTableConfig(HoodieWriterUtils.scala:131)
        at 
org.apache.hudi.HoodieWriterUtils.validateTableConfig(HoodieWriterUtils.scala)
        at 
org.apache.hudi.utilities.deltastreamer.HoodieDeltaStreamer$DeltaSyncService.<init>(HoodieDeltaStreamer.java:647)
        at 
org.apache.hudi.utilities.deltastreamer.HoodieDeltaStreamer.<init>(HoodieDeltaStreamer.java:156)
        at 
org.apache.hudi.utilities.deltastreamer.HoodieDeltaStreamer.<init>(HoodieDeltaStreamer.java:129)
        at 
org.apache.hudi.utilities.deltastreamer.HoodieDeltaStreamer.main(HoodieDeltaStreamer.java:559)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at 
org.apache.spark.deploy.JavaMainApplication.start(SparkApplication.scala:52)
        at 
org.apache.spark.deploy.SparkSubmit.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:951)
        at 
org.apache.spark.deploy.SparkSubmit.doRunMain$1(SparkSubmit.scala:180)
        at org.apache.spark.deploy.SparkSubmit.submit(SparkSubmit.scala:203)
        at org.apache.spark.deploy.SparkSubmit.doSubmit(SparkSubmit.scala:90)
        at 
org.apache.spark.deploy.SparkSubmit$$anon$2.doSubmit(SparkSubmit.scala:1039)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:1048)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to