FREE TOOL

Turn a CSV into a CREATE TABLE statement.

By Chris Davidson, founder of yForest · Updated September 26, 2026

Paste rows, pick a dialect, get column types and quoting handled correctly. No upload, no account, nothing leaves your browser.

Paste a CSV, get a CREATE TABLE.

Runs entirely in your browser. Nothing you paste or upload is sent anywhere.

Type inference: leading-zero values (like ZIP codes) stay text on purpose; a column is only boolean if every value is strictly 0/1 or true/false with nothing else mixed in.

How the type inference works

The tool reads every non-empty value in a column and classifies each one: whole number, decimal, boolean, ISO date, ISO timestamp, or text. The column's final type is the tightest type that fits every value, with a few deliberate exceptions. A value like 007 or a ZIP code stays text even though it looks numeric, because a leading zero means the value carries information a number type would silently drop. A column only becomes BOOLEAN when every value is strictly true/false or strictly 0/1 with nothing else present; a column containing 0, 1, and 2 is an integer, not a flag. Empty cells never force a column to text on their own, they just make the column nullable.

A worked example

Paste this into the tool and pick PostgreSQL:

id,name,signup_date,active,balance,zip
1,"Doe, Jane",2026-01-15,1,102.50,00501
2,Bob,2026-02-20,0,0.00,90210

The tool sees id as a small integer, name as a short string with an embedded comma handled correctly because it's quoted, signup_date as an ISO date, active as boolean because every value is 0 or 1 and nothing else, balance as a decimal with two-digit scale, and zip as text specifically because of the leading zero on 00501. Output for PostgreSQL:

CREATE TABLE "customers" (
  "id" INT NOT NULL,
  "name" VARCHAR(50) NOT NULL,
  "signup_date" DATE NOT NULL,
  "active" BOOLEAN NOT NULL,
  "balance" DECIMAL(6,2) NOT NULL,
  "zip" VARCHAR(50) NOT NULL
);

What changes by dialect

Same CSV, different output shape. BigQuery uses backtick quoting and its own type names: INT64 instead of INT or BIGINT, STRING instead of VARCHAR, NUMERIC(p,s) instead of DECIMAL(p,s). Snowflake and Databricks both use TIMESTAMP_NTZ-style handling for a bare ISO timestamp with no offset, since neither assumes a timezone you didn't specify. MySQL and Redshift stick closer to standard SQL types with backtick or double-quote identifiers respectively. If you check the COPY/LOAD checkbox, the tool adds a matching load statement, for example a BigQuery bq load command or a Snowflake COPY INTO with a file format clause, so you have both halves in one place instead of writing the load step from memory afterward.

Where the guess can be wrong

A type sniffer working off a sample can't know your intent, only your data. A column of all whole numbers under a few thousand rows might really be a foreign key you'd rather keep as BIGINT for headroom, and the tool has no way to know that from ten sample rows. A date column where every value happens to fall on the first of the month is still a date, but the tool can't tell you whether it should be a partition key. Treat the generated DDL as a correct starting point for a normal load, not a finished schema decision, and adjust anything where you have context the file doesn't carry, like which columns should be primary keys or which should allow nulls even though every sample row happens to be filled in.

When to reach for QueryFlow instead

This tool stops at the CREATE TABLE statement. Getting the CSV's rows actually into that table, on a schedule, with retries if a connection drops, is a different problem. QueryFlow's CSV and Excel connector reads a local file straight into any of its nine connectors and can run that load again automatically on a schedule, which is the part a generated DDL statement was never going to do by itself.

Sources

Free tools
QueryFlow Studio $9.99/mo · $99/yr
QueryFlow Pipelines $29.99/mo · $199.99/yr

Frequently asked

Does any of my CSV data leave my browser?

No. Parsing and type inference both run in JavaScript in your browser tab. Nothing is uploaded or sent to a server.

Why did my ZIP code column come out as text instead of a number?

Any value with a leading zero, like 00501, is kept as text on purpose. Storing it as an integer would silently drop the leading zero and corrupt the value.

Can it handle a column with some empty cells?

Yes. Empty cells are skipped when inferring the type and just make the column nullable instead of NOT NULL; they don't force the whole column to text.

Why is a column with only 0 and 1 sometimes an integer, not a boolean?

If every value in the column is strictly 0 or 1 it's treated as boolean. If any other number shows up, like a 2, the tool treats the whole column as an integer instead.

Does this replace an actual schema migration tool?

No. It gives you a correct starting CREATE TABLE for a normal load. Constraints, indexes, and partitioning decisions still need your own judgment.

Generated the DDL. Now load the data.

QueryFlow reads CSV and Excel files straight into nine connectors, on a schedule.

Start 14-day free trial

No credit card. 14 days. Cancel in one click.