Real CSVs are rarely clean, and knowing the options turns a failing import into a one-line fix.
read_csv runs a sniffer that samples the file to guess the delimiter, quote and escape characters, whether there is a header, and the type of each column. It is usually right, but you can override anything:
delim,quote,escape,headerfor the dialectcolumns = {'id': 'INTEGER', 'name': 'VARCHAR'}to fix names and types (disables type detection), ortypes = {...}to override only somedateformat/timestampformatfor non-ISO dates, e.g.'%d/%m/%Y'nullstrfor values like'NA'that should be NULLall_varchar = trueto load everything as text and cast laterignore_errors = trueto skip rows that fail to parse, andstore_rejects = trueto keep them in areject_errorstable for inspectionfilename = trueadds a column with the source file name
sniff_csv('file.csv') shows what the sniffer decided, which is the first thing to run when a load goes wrong. A common failure is a column inferred as integer from the sample that later contains text; increase sample_size (or -1 for the whole file) or set the type explicitly.
CSV parsing is parallel and fast, but it is still parsing: convert large CSVs to Parquet once if they will be read repeatedly.
Example
import duckdb, os, tempfile
os.chdir(tempfile.mkdtemp())
with open("people.csv", "w") as f:
f.write("name;born;score\nAnn;03/04/1990;7\nBob;NA;x\nCy;12/11/1985;9\n")
rel = duckdb.sql("""
SELECT * FROM read_csv('people.csv', delim = ';', header = true,
dateformat = '%d/%m/%Y', nullstr = 'NA',
columns = {'name': 'VARCHAR', 'born': 'DATE', 'score': 'INTEGER'},
ignore_errors = true)
""")
print(rel.fetchall())
# [('Ann', datetime.date(1990, 4, 3), 7), ('Cy', datetime.date(1985, 11, 12), 9)]Remember
- The sniffer guesses dialect, header and types from a sample
columns/types,dateformatandnullstrfix most bad guessesignore_errorsskips bad rows;store_rejectskeeps them for review- Run
sniff_csvto see what was detected
Watch out for
- Silently dropping rows with
ignore_errors = trueand never checking how many were rejected.