Is it possible to add extra fields that may be mis...
# troubleshooting
l
Is it possible to add extra fields that may be missing from records? If so, how? For instance:
Copy code
{"a": 1, "b": 2, "c": 3}
{"a": 4, "b": 5}
{"a": 6}
Say I want to have fields a,b,c for all the different messages above, even if they're missing?
t
What target are you sending this to? If it’s a database then I would expect it to return null for those fields. This also may be appropriate for the Map layer that @aaronsteers has been working on for the SDK
a
@lasse_vang_gravesen - I don’t think this is possible today, since most of the time the contract between tap and target “EL” part of the pipeline is to replicate exactly what was in the pipeline. But yes, there are possible ways to extend that capability, including adding defaults and other inline transformations. You found the
pipelinewise-transform-field
but I don’t think that supports the feature you are looking for. To @taylor’s point, we do plan to deliver a new “stream_maps” feature in the SDK this month, which would certainly be usable for this purpose once added here as a Meltano feature as well. Can you say a little more about your use case? Any reason not to replace those defaults in a “T” transform layer after the EL completes? For most cases, we would recommend doing the transform after the EL pipeline, for instance in dbt, so that you know you have exactly replicated the upstream source with fidelity.
l
@aaronsteers hi, my problem is that I want to read from a tap (kafka) and dump to a CSV file using target-csv, but the kafka topic contains messages of different types like in my example
The csv target dumps using the header of the first message, so if any of the other messages differ it gets screwed up
for example:
Copy code
{"a": 1, "b": 2, "c": 3}
{"a": 1, "c": 3}
{"c": 3}
Would produce a CSV file:
Copy code
a,b,c
1,2,3
1,3
3
so what I wanted to do was add the missing fields as nulls if they arent present
a
@lasse_vang_gravesen, I see now. Thanks for the extra explanation. Looks like a column ordering bug in the CSV target. Is your final plan to land in another system or just CSV? For instance, you might consider the jsonl target instead if you are only trying to land to a flat file, or there's also a target-s3-csv option which is more production-ready if you plan to ultimately load to S3.
l
Ultimately I want it to land in Redshift, and I just discovered that the redshift loader actually puts everything into S3 first
I wanted to load into S3 for archive and replayability purposes
the Redshift loader puts it into S3, then loads into Redshift from S3, then deletes it from S3
a
Yeah, that makes total sense. You might consider if other variants of target-Redshift retain the CSV. I wanted to same feature actually (
retain_s3_files
) in my Snowflake target so I forked the target and removed the "delete()" code. :) But someone might have done this already for Redshift. It's worth checking.
l
that was my next thing anyway, fork the redshift target and get rid of the deletion thing
Re the CSV thing: It's not a ordering issue, it's that the csv target uses the first event in a stream to write the header
so if you have mixed events, for instance domain events, that contain differing fields the keys will all be screwed up because the header is defined by the very first event
My original query was then "can I make these events consistent in meltano/singer/pipelinewise, by adding extra fields if they're missing?"
and it seems like the answer to that is "not easily"
Ill proceed on the path of forking the redshift target now, and see if I can make that workable
Appreciate the input!
a
That's correct. "Not easily." And yes, I can see your point regarding ordering vs when headers are written. Long and short is that the target should be adapting to new schemas. But because the generic target-csv doesn't usually get used in production scenarios, it doesn't deal as well with changing schemas. I expect other production-grade targets should deal with this better. I did also just check the pipelinewise variant for target-Redshift and did not see the retain-csv-files option there. https://github.com/transferwise/pipelinewise-target-redshift
I don't know if target-csv supports an input catalog, but in theory you could provide a custom catalog that contains your full list of columns. For targets which support it, that custom catalog (with all nullable columns declared) would give the full schema upfront at the start of the stream.
l
Should've been more obvious what the redshift target was using s3 and putting csv files into it, I wouldn't have spent time on the other targets if I knew that
I did try using a catalog, didn't do anything
but I'll proceed with the redshift target for now, thanks so far!
a
Sounds like you are on the right track. 👍 And yeah, sorry for the confusion around the internals of the target-redshift.
Most big data targets do something like this, but it's completely understandable to start with the CSV target if you don't know csv-writing is built-in on those others.