SQLite to Parquet Converter

Move a local database into a format a data stack can query. Every table is offered, columns are typed from their values, and DuckDB writes the file in the page.

To convert SQLite to Parquet, drop your .db, .sqlite or .sqlite3 file above. Every table with rows is listed, and the one you choose is typed one column at a time and written as a Parquet file by DuckDB running in your browser, with real BIGINT, DOUBLE, BOOLEAN, DATE and VARCHAR columns.

Want to join two tables before writing? Open the app

Local database, analytical destination

SQLite is where a lot of data starts: an application's store, a device's local cache, a scraper's output, a research script that needed somewhere to put results. It is genuinely good at that job and it is not an analytical database.

Once the question becomes "aggregate three years of this by month", the row-oriented file on a laptop stops being the right container. Parquet is, and every analytical engine reads it.

The other reason is sharing. A .db file is opaque to everyone without a client, while a Parquet file drops straight into a lake, a notebook or a warehouse external table.

Several tables, offered rather than guessed at

A database file holds many tables the way a workbook holds many sheets, so it reuses the same control. The first table with rows converts on arrival and every table that has rows is listed underneath with its name, so switching is one click.

Empty tables are left out of the list rather than offered as choices that produce nothing. Schema-migration bookkeeping tables are usually the first thing in a database by creation order, so an alphabetical or creation-order pick would hand you those every time.

Views are not included. A view is a query rather than stored data, and running it would mean interpreting SQL this reader does not execute. If you need a view's output, materialise it into a table first with a CREATE TABLE AS in your own client.

Typing a source that does not enforce types

This is the interesting part of the conversion. Parquet requires each column to have exactly one type and SQLite guarantees no such thing: its declared types are affinities, and a column can genuinely hold an integer on one row and a string on the next.

So the type is decided from the values rather than the declaration. A column becomes an integer type only when every value in it is a whole number, a floating type only when every value is numeric, a boolean only when every value is a real true or false, and VARCHAR otherwise.

The consequence worth knowing in advance is that a column declared INTEGER in the schema can come out as VARCHAR in the Parquet, and that is correct: one row somewhere in the table has a string in it, and writing the column as an integer would mean either failing or silently changing that value.

What the file ends up with

  • BIGINT where every value is a whole number, keeping identifiers and counts exact.
  • DOUBLE where the column has fractions in it.
  • BOOLEAN where every value is a real true or false.
  • DATE where the column holds exact ISO date text throughout, which is what makes a date predicate push down at query time.
  • VARCHAR for everything else, including padded codes, mixed columns and dates stored as integer timestamps.

Blobs, and doing better than one table at a time

A BLOB column has no useful Parquet representation here and carries a placeholder rather than its bytes. If the blobs are the data you care about, extracting them is a different job and a script with the sqlite3 library is the right tool.

The bigger limitation is that this converts one table per file. Analytical questions almost always span tables: orders joined to customers joined to regions.

Doing that join first is much better than writing three Parquet files and joining them later, and it is one link away. The editor opens the same database with DuckDB's full query surface, so the Parquet you export is the shape of the question rather than the shape of the schema.

Nothing is uploaded, and that is the point

The hosted converters for these formats all want the file. That is a fine trade for a photograph and a poor one for a database extract, which is what these files almost always are: customer tables, transaction detail, event streams with identifiers in them.

Everything here runs inside the page. The file is read by JavaScript in your tab, the output is built there, and the download comes out of memory. Nothing is sent, stored or logged, and once the page has loaded the tool works with the network off.

The practical ceiling is your tab's memory rather than an upload quota. Past a hundred megabytes or so the full editor streams and is the better route.

Frequently Asked Questions

Do I need sqlite3, Python or DuckDB installed?

None of them. The database is opened by JavaScript and DuckDB compiled to WebAssembly writes the Parquet, both inside your browser tab. The engine downloads once, a few megabytes, and is cached.

Why is a column declared INTEGER written as VARCHAR?

Because one row somewhere in the table has a string in it. SQLite's declared types are affinities rather than constraints, and Parquet needs one type per column, so the type is decided from the values. Writing it as an integer would mean failing or silently changing that value.

Which table gets converted?

The first with rows, with every table that has rows listed so you can switch. One table per file, because Parquet holds one table. If you want a join, do it before exporting rather than after.

Do dates become DATE columns?

Only when the column holds exact ISO date text throughout. SQLite has no date type, so dates stored as integer timestamps come through as numbers, and deciding whether those are seconds, milliseconds or Julian days would be a guess.

What happens to BLOB columns?

They carry a placeholder rather than their bytes. If the blobs are what you need, extracting them is a different job and a script using the sqlite3 library is the right tool for it.

Can I join tables before exporting?

Not on this page, and it is usually the better move. The editor link opens the same database with DuckDB's full query surface, so you can export the shape of your question rather than the shape of the schema.

Take the local database somewhere analytical

Every table offered, real column types, columnar and compressed, all in your browser.

Back to the converter