sql 283 lines · 2 tabs

Efficient data import and export strategies

Maria Garcia Feb 2026
2 tabs
-- Import CSV with COPY (fastest method)
COPY users (username, email, age, created_at)
FROM '/path/to/users.csv'
WITH (
  FORMAT csv,
  HEADER true,
  DELIMITER ',',
  QUOTE '"',
  NULL 'NULL'
);

-- Export to CSV
COPY users TO '/path/to/users_export.csv'
WITH (
  FORMAT csv,
  HEADER true,
  DELIMITER ',',
  QUOTE '"',
  NULL 'NULL'
);

-- Export query results
COPY (
  SELECT username, email, created_at
  FROM users
  WHERE status = 'active'
  ORDER BY created_at DESC
) TO '/path/to/active_users.csv'
WITH (FORMAT csv, HEADER true);

-- Import tab-delimited file
COPY products (sku, name, price)
FROM '/path/to/products.tsv'
WITH (FORMAT text, DELIMITER E'\t');

-- Import with different NULL representation
COPY sales (date, product_id, quantity, revenue)
FROM '/path/to/sales.csv'
WITH (FORMAT csv, NULL '\N');

-- Binary format (faster, PostgreSQL-specific)
COPY large_table TO '/path/to/data.bin'
WITH (FORMAT binary);

COPY large_table FROM '/path/to/data.bin'
WITH (FORMAT binary);

-- Stream from stdin (pipe from application)
COPY users (username, email) FROM STDIN WITH CSV;
-- Application sends data
-- \. to end

-- Stream to stdout
COPY users TO STDOUT WITH CSV HEADER;

-- psql \copy command (client-side, for non-superuser)
-- \copy users FROM 'users.csv' WITH (FORMAT csv, HEADER true);

-- Import large file efficiently
BEGIN;

-- Disable triggers during import
ALTER TABLE users DISABLE TRIGGER ALL;

-- Drop indexes temporarily
DROP INDEX IF EXISTS idx_users_email;
DROP INDEX IF EXISTS idx_users_username;

-- Import data
COPY users FROM '/path/to/large_users.csv' WITH (FORMAT csv, HEADER true);

-- Recreate indexes
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_username ON users(username);

-- Re-enable triggers
ALTER TABLE users ENABLE TRIGGER ALL;

COMMIT;

-- Analyze after large import
ANALYZE users;

-- Import with data transformation
COPY (
  SELECT
    id,
    UPPER(username) AS username,
    LOWER(email) AS email,
    CURRENT_TIMESTAMP AS imported_at
  FROM staging_users
) TO '/path/to/transformed.csv' WITH CSV;

-- Handle import errors (PostgreSQL 14+)
COPY users FROM '/path/to/users.csv'
WITH (
  FORMAT csv,
  HEADER true,
  ON_ERROR ignore  -- Skip error rows
);

-- Export JSON
COPY (
  SELECT jsonb_build_object(
    'id', id,
    'username', username,
    'email', email,
    'created_at', created_at
  )
  FROM users
) TO '/path/to/users.json';

-- Export JSONL (JSON Lines)
COPY (
  SELECT row_to_json(users.*)
  FROM users
) TO '/path/to/users.jsonl';

-- Incremental export (only new/updated records)
COPY (
  SELECT *
  FROM users
  WHERE updated_at > (
    SELECT last_export_time
    FROM export_log
    WHERE table_name = 'users'
  )
) TO '/path/to/users_incremental.csv' WITH CSV HEADER;

-- Update last export time
UPDATE export_log
SET last_export_time = CURRENT_TIMESTAMP
WHERE table_name = 'users';
2 files · sql Explain with highlit

Data import/export moves data between systems. I use COPY for bulk operations—orders of magnitude faster than INSERT. CSV format balances simplicity and performance. Binary format is faster but less portable. Streaming import handles large files without memory issues. Parallel import utilizes multiple cores. ETL pipelines transform data during import. Understanding delimiters, quoting, escaping prevents data corruption. Header rows simplify column mapping. NULL handling requires explicit configuration. Foreign key constraints can slow imports—disable temporarily. Batching balances transaction size and performance. pg_dump exports databases reliably. JSON export integrates with modern APIs. Proper import/export strategy is essential for data migration, backups, analytics pipelines.


Related snips

sql
-- Simple function
CREATE OR REPLACE FUNCTION get_full_name(
  first_name VARCHAR,
  last_name VARCHAR
)
RETURNS VARCHAR AS $$

Stored procedures and functions in PostgreSQL

postgresql stored-procedures functions
by Maria Garcia 2 tabs
ruby
require "csv"

class PeopleCsvStream
  include Enumerable

  HEADERS = %w[id full_name email signed_up_at plan].freeze

Resilient CSV Export as a Streamed Response

rails performance streaming
by codesnips 3 tabs
ruby
# Vulnerable: user input is concatenated directly into SQL.
email = params[:email]
password = params[:password]

sql = "SELECT * FROM users WHERE email = '#{email}' AND password_hash = '#{password}'"
user = ActiveRecord::Base.connection.execute(sql).first

SQL injection prevention with unsafe and safe query patterns

sql-injection owasp database
by Kai Nakamura 3 tabs
sql
-- EXPLAIN ANALYZE (actual execution statistics)
EXPLAIN ANALYZE
SELECT u.username, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at >= '2024-01-01'

Advanced query optimization techniques

database optimization query-performance
by Maria Garcia 2 tabs
python
from django.db.models import Count, Avg, Sum, Q, F
from django.views.generic import TemplateView
from products.models import Product, Order, OrderItem


class DashboardView(TemplateView):

Django aggregation with annotate for statistics

django python database
by Priya Sharma 1 tab
ruby
class ReportQuery
  SQL = <<~SQL.freeze
    SELECT date_trunc('day', events.created_at) AS day,
           count(*) AS total,
           count(*) FILTER (WHERE events.kind = 'purchase') AS purchases
    FROM events

Safe Raw SQL with exec_query + Binds

rails activerecord sql
by codesnips 2 tabs

Share this code

Here's the card — post it anywhere.

Efficient data import and export strategies — share card
Link copied