A CSV file is a transport format, not a ready-made database table. The import must agree on column order, delimiter, encoding, null representation, and value rules. Database engines provide different bulk tools, including PostgreSQL COPY and MySQL LOAD DATA. This reference explains those differences and builds a staging workflow that separates raw text from accepted rows. You will create a PostgreSQL staging table, use psql to transfer a client-side file, review its records, and export selected data. Use a disposable database and a CSV you are authorized to process. You will also plan exports with safe file access and a spreadsheet formula policy.
Write a format contract before loading
Document the header, field order, delimiter, quote behavior, line endings, encoding, date format, and representation of missing values. CSV can contain quoted commas and newlines, so splitting each line on commas is not a reliable parser. A blank field may mean empty text or NULL depending on the tool and options. Product codes and postal codes can contain leading zeros and should remain text if those zeros matter. Decide whether prices use a dot decimal separator and whether currency appears in a separate column. A header label does not always cause a tool to match columns by name; many bulk commands still use the declared positional column list. Verify the specific tool rather than assuming a spreadsheet export defines everything.
Use staging for untrusted or inconsistent data
Load raw fields into text columns in a staging table with a job ID and source-row identity where needed. Validate required keys, date and number formats, ranges, duplicates, and parent references before promotion. A direct bulk load into production can fail partway or silently coerce values according to engine and mode. Staging makes rejected rows reviewable and keeps accepted business tables consistent. Use explicit INSERT ... SELECT column lists when promoting data. Decide whether one invalid row cancels the job or only that row. Preserve counts for raw, accepted, rejected, and duplicate records. Protect sensitive staging data and clean it under a documented retention policy.
Understand PostgreSQL server and client loading
PostgreSQL COPY with a filename operates from the database server's filesystem and requires the relevant permissions. COPY ... FROM STDIN transfers data through the connection. The psql client command \copy manages client-side files and uses that connection transfer, so it has different file-location and privilege implications. Do not ask for broad server-file roles merely because a developer's laptop CSV is unavailable on the server. Choose FORMAT csv, HEADER behavior, column list, and null policy explicitly. Version-specific error-tolerance options should be verified against the selected PostgreSQL release before use. A successful bulk command still needs business validation if staging contains raw text.
Understand MySQL loading policy
MySQL LOAD DATA INFILE reads a server-side file under its server configuration and privileges. LOAD DATA LOCAL INFILE transfers a client-side file and depends on both client and server policy. LOCAL is not a universal harmless workaround; review its security behavior and enable it only where needed. secure_file_priv and account permissions can restrict server file operations. Set field terminator, enclosure, escaping, line endings, header skip, and character set according to the actual file. Strict modes, warnings, and conversion behavior affect invalid data handling. Check warnings and counts rather than declaring success from a completed command alone. Use a staging design when the source is not already trusted and validated.
Export an intentional result set
Select explicit columns and a deterministic order so the exported format is stable. Apply authorization and tenant filters before export. A report with sensitive rows needs controlled access and may require audit information. PostgreSQL COPY ... TO STDOUT can stream query results through a connection, while server filenames have server-side access rules. MySQL INTO OUTFILE likewise writes on the server under restrictions and generally will not overwrite an existing file. Application-side CSV writing is often useful for downloads and portability. Use a real CSV serializer rather than string joining. Decide whether the export is a live query or a consistent snapshot, especially when it spans a long-running job.
Protect consumers and reconcile results
Spreadsheet software can interpret cells beginning with formula markers as executable formulas; ordinary CSV quoting does not necessarily prevent that. Apply a documented spreadsheet-safe text policy when that is the consumer, while preserving exact machine-to-machine exports separately if needed. Use controlled download filenames and avoid server path exposure. Encrypt and access-control sensitive exports under the data policy. Reconcile row counts and representative values after import, including encoding, dates, nulls, and leading zeros. Reruns need a stable key or idempotency design rather than duplicate insertion. Test a quoted comma, multiline field, blank value, malformed date, duplicate code, and wrong column count. These cases reveal whether the contract is truly understood.
Practice task and worked solution
Plan a PostgreSQL import from a developer's local products.csv. Use psql \copy into a staging table rather than assuming the database server can read the laptop path. Specify the positional column list and CSV contract. The solution validates codes, decimal prices, nonnegative stock, duplicates, and category references before INSERT ... SELECT promotion. Produce rejected-row counts and a reviewed rerun policy. Then design a browser CSV export using an application serializer and a spreadsheet formula policy for names. Explain how the approach changes for MySQL LOAD DATA and which LOCAL settings and risks must be reviewed. Do not enable broad file privileges just to avoid understanding file location.
Worked PostgreSQL client import and export
Create this staging table in the intended disposable database. Its fields remain text so that malformed quantities can be reviewed before conversion. The example CSV header is code,quantity, followed by rows 0012,0 and 0040,7. Save it as stock.csv on the machine running psql. The client file path is relative to that client's working directory; it is not a database-server path. The role needs appropriate table privileges, and the installed psql must connect to the selected test database.
CREATE TABLE stock_stage (
code TEXT,
quantity_text TEXT
);Run these commands inside psql. Backslash-copy is a psql command rather than generic SQL, and each command should remain on one line.
\copy stock_stage (code, quantity_text) FROM 'stock.csv' WITH (FORMAT csv, HEADER true)
\copy (SELECT code, quantity_text FROM stock_stage ORDER BY code) TO 'stock-review.csv' WITH (FORMAT csv, HEADER true)Expected result: two raw staging rows are imported, and stock-review.csv is written on the client machine with a header and those rows in code order. PostgreSQL's default CSV null rules apply here; agree on a different explicit null representation if your supplier distinguishes blank text from missing values differently. The declared column list is positional even though the file has a header. Review quantities, required codes, duplicates, and category references before promoting rows into a constrained business table. Avoid casting malformed quantity text directly: reject it or use the selected validated conversion strategy. The export is a review file, not proof that every row is accepted. Restrict its access if the actual feed contains confidential data.
Continue learning
Review data cleaning, row changes, and constraints.
See PostgreSQL COPY and MySQL LOAD DATA for dialect-specific file and parsing rules.
Importing and Exporting CSV Data Examples
Each example shows the code, the output it produces and what each part does.
Review raw stock before promotion
This generic query models a staging review without touching external files. All values are text until the business checks accept them.
The review preserves leading-zero codes and identifies the missing code. It deliberately does not cast quantity_text before format validation. Safe conversion syntax differs by dialect and belongs in the selected engine's promotion step.
WITH staged (source_row, code, quantity_text) AS (
SELECT 1, '0012', '0'
UNION ALL SELECT 2, '0040', '7'
UNION ALL SELECT 3, '', '3'
)
SELECT source_row, code, quantity_text,
CASE WHEN code = '' THEN 'missing code' ELSE 'review quantity' END AS review
FROM staged
ORDER BY source_row;source_row | code | quantity_text | review
1 | 0012 | 0 | review quantity
2 | 0040 | 7 | review quantity
3 | | 3 | missing codeImporting and Exporting CSV Data FAQ
Does CSV HEADER always map names?
Not necessarily. In PostgreSQL's COPY, HEADER mainly tells the database to skip the first line; columns are still matched by position unless your tool or version does more. Verify positional and tool behaviour, and list the target columns explicitly in the import command.
Where does server COPY read a filename?
On the database server, not on your laptop. COPY sales FROM '/data/sales.csv' opens a file in the server's file system and needs special privileges. To send a local file, use a client-side command or your driver's copy support.
Is \copy the same?
No. \copy is a psql client command managing client-side transfer: it reads or writes the file on your computer and streams it through the connection, so it works without server file access. Its options mirror COPY.
Does CSV quoting stop spreadsheet formulas?
Not reliably. A cell beginning with =, +, - or @ can still be interpreted as a formula when the file is opened in a spreadsheet. Define a consumer-specific policy for exports, such as prefixing such values with an apostrophe.
How do I import a CSV file into MySQL or SQLite?
MySQL uses LOAD DATA INFILE, or LOAD DATA LOCAL INFILE for a file on the client, with options for the delimiter and header lines. The SQLite shell uses .mode csv followed by .import file.csv table. In both cases, import into a staging table first and validate before inserting into real tables.
Importing and Exporting CSV Data Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
A CSV is on your laptop but COPY runs on a remote PostgreSQL server. What fits?
Importing and Exporting CSV Data Quiz
2 questions to check what you learned.
Why use text staging columns for an inconsistent feed?
- To allow malformed fields to enter production unchanged
- To let implicit casts decide the supplier's business formats
- To replace all future integrity constraints with manual review
- Validate representations before converting and promoting them
What should a bulk-load success report include?
- Accepted, rejected and warning outcomes under the chosen policy
- Only a successful command exit without checking warnings or rejected rows
- Only the number of columns in the destination table
- Only the CSV filename and its modification time