Oh boy, I love debugging!
And today I really had to debug DataLoader!
I do a lot of stuff with DataLoader — see my previous blogs on the topic. But I’ve always uploaded to Salesforce from a PostgreSQL database — never extracted.
DataLoader allows a job to be configured where a SOQL query is run, the data is extracted from Salesforce and the results are inserted into a database. The documentation is woeful on this whole topic, but fortunately DataLoader comes with sample process-conf.xml and database-conf.xml files that contain some examples.
The basic method is:
process-conf.xmldefines the job and includes the SOQL in aextractionSOQLparameter- An
SDLfile defines the field mapping between Salesforce and the output database-conf.xmldefines the SQL statement to use, plus the parameter types
First hint: The Field names in the SDL file are case-sensitive. Use “ID” instead of “Id” and the field won’t come across.
Second hint: All fields come across in quotes. This totally destroys any attempt to load numbers!
Here’s part of the database-conf.xml that I used:
<bean id="extractMegaphoneQuery"
class="com.salesforce.dataloader.dao.database.SqlConfig" singleton="true">
<property name="sqlString">
<value>
INSERT INTO renewals_megaphone (
period, megaphone_date, opportunity_name, reason_lost, owner, expiry_date, product, years_owned)
VALUES (@period@, @megaphone_date@, @opportunity_name@, @reason_lost@, @owner@,
@expiry_date@, @product@, @years_owned@)
</value>
</property>
<property name="sqlParams">
<map>
<entry key="period" value="bigint"/>
<entry key="megaphone_date" value="java.sql.Date"/>
<entry key="opportunity_name" value="java.lang.String"/>
<entry key="reason_lost" value="java.lang.String"/>
<entry key="owner" value="java.lang.String"/>
<entry key="expiry_date" value="java.sql.Date"/>
<entry key="product" value="java.lang.String"/>
<entry key="years_owned" value="integer"/>
</map>
</property>
</bean>
You’ll notice I have two fields that are numbers — period (bigint) and years_owned (integer). When trying to load these fields into my database, I kept getting the message:
Sql error: ERROR: column "period" is of type bigint but expression is of type character varying.
org.postgresql.util.PSQLException: ERROR: column "period" is of type bigint but expression is of type character varying
There was no way that I could convince DataLoader that the field was numeric — I tried lots of java.lang.Integer type entries in the sqlParams, but didn’t help.
I then changed the output to csvWrite instead of databaseWrite so that I could see the output, and it came through like this:
"PERIOD","MEGAPHONE_DATE","OPPORTUNITY_NAME","REASON_LOST","OWNER","EXPIRY_DATE","PRODUCT","YEARS_OWNED"
"83823.0","2010-06-08","Joe Smith","Invalid","John","2010-03-14","a0624004000qRtkgA2","3.0"
You’ll notice that the first and last columns are meant to be numbers, but they are coming through in quotation marks. That’s what was causing the database load to fail!
So, I updated my SQL to convert the strings to numbers:
<property name="sqlString">
<value>
INSERT INTO renewals_megaphone (
period, megaphone_date, opportunity_name, reason_lost, owner, expiry_date, product, years_owned)
VALUES (@period@::numeric, @megaphone_date@, @opportunity_name@, @reason_lost@, @owner@, @expiry_date@, @product@, @years_owned@::numeric)
</value>
</property>
This successfully cast the strings into numbers and they finally got stored in the database (which automatically ignored the decimal places when converting to bigint and integer).
I hope the blog post saves other people similar problems!
The Bottom Line
- DataLoader can extract data and insert it into a database
- Numbers are quoted on export and cause database errors
- I type-cast the
stringintonumericto enable the database to load it
February 10th, 2011 at 8:19 am
You have a great qoute in your blog post . . . ‘DataLoader allows a job to be configured where a SOQL query is run, the data is extracted from Salesforce and the results are inserted into a database. The documentation is woeful on this whole topic . . .’ The documentation is WOEFUL!!! According to the errors I am getting my problems seem to lie in my database-conf.xml file.
I was wondering if you could post a sample of your dbDataSource bean? Also, I have tried to use both jdbc and jtds jar files, perhaps I dont have mine in the right place? I have put them in the same folder as the process-conf and database conf xml files.
I have posted to the developerforce site but no replies . . . here is my dbDataSource bean:
March 12th, 2011 at 1:26 am
I have a Money data type field and was getting data type conversion error.
I tried as suggested with Data Loader API 21 and it didn’t work. Gott error “Sql error: Incorrect syntax near ‘::’”
To circumvent the issue, I simply changed the data type of Money field to Float and the data loader implisitly converts it fine for me..