Skip to main content

beaver banner

PyPI Version Python Versions Rust Version GitLab Python Implementation License

Beaver

Turn raw data into ready-to-run SQL in one command.

Beaver is a high-performance data conversion tool written in Rust. It streams structured CSV, JSON and NDJSON data from files, standard input or pipeline streams and outputs validated, dialect-accurate SQL statements.

Designed for low overhead and speed, Beaver operates as a zero-dependency CLI binary or as a native Python extension compiled via PyO3.

Table of Contents

Features

  • Streaming Processing: Streams continuous inputs (CSV, JSON arrays, NDJSON) with minimal footprint.
  • Multi-Dialect Support: Supports PostgreSQL, MySQL and SQLite identifier quoting and value escaping rules.
  • Automatic Type Inference: Infers column types on the fly.
  • DDL & DML Generation: Generates schema definitions alongside value-escaped statements.
  • Primary Keys: Mark existing columns (including composite keys) as the primary key, or add an auto-increment id column.
  • Dual Runtime Interface: Available as a standalone CLI tool and a C-extension Python Library beaver-box.

Installation

pip install beaver-box

Verify installation:

beaver --version

Command-Line Usage

beaver [OPTIONS]

Basic Conversion

# Convert CSV to SQL
beaver -i data.csv -o data.sql -t users --create-table

# Convert JSON to SQL
beaver -i data.json -f json -o data.sql -t users --create-table

Stream from Standard Input (Pipelines)

Pipe JSON or CSV data directly into Beaver:

cat data.ndjson | beaver -f json -t users -d postgres

Generate Table Schema (DDL) and Inserts Include the --create-table flag to prepend a CREATE TABLE IF NOT EXISTS definition:

cat data.csv | beaver -f csv -t users -d mysql --create-table

Convert File and Write Output Directly to File

beaver -i data.csv -o user_data.sql -t users -d sqlite --create-table

Create a Primary Key

Use -k / --primary-key to make one or more existing columns the primary key. Separate column names with commas for a composite key:

# Single column
beaver -i data.csv -t users --create-table -k id

# Composite key
beaver -i book.csv -t orders --create-table -k user_id,book_id

If your data has no suitable column, use --auto-id to add a new auto-increment id column that the database fills in:

beaver -i data.csv -t people --create-table --auto-id

--primary-key and --auto-id only affect the generated CREATE TABLE statement, so they require --create-table. They cannot be used together.

CLI Flags Reference

Option Short Description Default
--input -i Input file path (reads from stdin if omitted) stdin
--output -o Output file path (writes to stdout if omitted) stdout
--table -t Target database table name beaver_table
--format -f Input format (csv, json) csv
--dialect -d SQL dialect (postgres, sqlite, mysql) postgres
--create-table Generate CREATE TABLE IF NOT EXISTS DDL false
--primary-key -k Existing column(s) to use as primary key, comma-separated. Requires --create-table none
--auto-id Add an auto-increment id primary key column. Requires --create-table false
--help -h Print help information
--version -V Print version information

The json format accepts both a JSON array of objects and newline-delimited JSON (NDJSON). Beaver detects which one it is from the first character of the input.

Example Output

Given data.csv:

id,name,active,joined
1,Karen,true,2024-03-01
2,G'Christian,false,2024-04-12

Running beaver -i data.csv -t users -d postgres --create-table produces:

CREATE TABLE IF NOT EXISTS "users" (
  "id" BIGINT,
  "name" TEXT,
  "active" BOOLEAN,
  "joined" DATE
);
 
INSERT INTO "users" ("id", "name", "active", "joined") VALUES (1, 'Karen', TRUE, '2024-03-01');
INSERT INTO "users" ("id", "name", "active", "joined") VALUES (2, 'G''Christian', FALSE, '2024-04-12');

With a primary key

Running beaver -i data.csv -t users -d postgres --create-table -k id marks the id column as the primary key. Key columns become NOT NULL, and a PRIMARY KEY clause is added:

CREATE TABLE IF NOT EXISTS "users" (
  "id" BIGINT NOT NULL,
  "name" TEXT,
  "active" BOOLEAN,
  "joined" DATE,
  PRIMARY KEY ("id")
);

With an auto-increment id

Given data.csv:

name,email
Karen,karen@example.com
Christian,christian@example.com

Running beaver -i data.csv -t users -d postgres --create-table --auto-id produces:

CREATE TABLE IF NOT EXISTS "users" (
  "id" BIGSERIAL PRIMARY KEY,
  "name" TEXT,
  "email" TEXT
);

INSERT INTO "users" ("name", "email") VALUES ('Karen', 'karen@example.com');
INSERT INTO "users" ("name", "email") VALUES ('Christian', 'christian@example.com');

The INSERT statements leave out id, so the database generates the values.

Python Usage

Beaver exposes C-extension functions for high-speed string and file conversion inside Python workflows. Each function returns the generated SQL as str.

Function Input
convert_csv_to_sql(csv_data, ...) CSV contents as a string
convert_json_to_sql(json_data, ...) JSON / NDJSON contents as a string
convert_csv_file_to_sql(path, ...) Path to a CSV file
convert_json_file_to_sql(path, ...) Path to a JSON / NDJSON file

All four accept the same keyword arguments:

Argument Description Default
table_name Target database table name "beaver_table"
create_table Prepend CREATE TABLE IF NOT EXISTS DDL False
dialect "postgres", "mysql" or "sqlite" "postgres"
primary_key Existing column(s) to use as primary key, comma-separated (for example "id" or "user_id,book_id"). Requires create_table=True None
auto_id Add an auto-increment id primary key column. Requires create_table=True False

Convert a File to SQL

  1. CSV
import beaver
 
sql = beaver.convert_csv_file_to_sql(
    "data/data.csv",
    table_name="users",
    create_table=True,
    dialect="postgres",
)
 
print(sql)
  1. JSON/NDJSON
import beaver
 
sql = beaver.convert_json_file_to_sql(
    "data/data.json",
    table_name="users",
    create_table=True,
    dialect="postgres",
)
 
print(sql)
  1. Write Output Directly to a .sql File

Beaver returns the generated SQL as a standard Python string, you can easily save it to a file using Python's built-in file handling:

import beaver

sql = beaver.convert_csv_file_to_sql(
    "data/data.csv",
    table_name="users",
    create_table=True,
    dialect="postgres",
)


with open("user_db.sql", "w") as f:
    f.write(sql)

print("Successfully generated user_db.sql!")

Convert a String to SQL

The *_to_sql functions take the data itself, not a file path:

import beaver
 
csv_data = "id,name\n1,Karen\n2,Christian\n"
 
sql = beaver.convert_csv_to_sql(
    csv_data, 
    table_name="users", 
    create_table=True
)

print(sql)

Convert a pandas DataFrame to SQL

Beaver works with plain strings, so a DataFrame goes in as CSV text. Use df.to_csv(index=False) and pass the result to convert_csv_to_sql:

import pandas as pd
import beaver
 
df = pd.DataFrame({
    "id": [1, 2],
    "name": ["Karen", "Christian"],
})
 
sql = beaver.convert_csv_to_sql(
    df.convert_dtypes().to_csv(index=False),
    table_name="users",
    create_table=True,
    primary_key="id",
)
 
print(sql)

pandas is not a dependency of Beaver. Install it separately with pip install pandas.

Create a Primary Key

Use an existing column (or several, comma-separated, for a composite key):

import beaver

sql = beaver.convert_csv_file_to_sql(
    "data/data.csv",
    table_name="users",
    create_table=True,
    primary_key="id",
)

print(sql)

Or let the database generate the key with an auto-increment id column:

import beaver

sql = beaver.convert_csv_file_to_sql(
    "data/data.csv",
    table_name="users",
    create_table=True,
    auto_id=True,
)

print(sql)

Error Handling

Exception Raised when
ValueError The input is malformed (for example, unbalanced quotes in CSV or invalid JSON)
ValueError A primary key option is invalid: the column is not in the data, primary_key and auto_id are used together, auto_id is used when the data already has an id column, or either option is used without create_table=True
OSError A file passed to a *_file_to_sql function cannot be opened

An unrecognized dialect string in Python falls back to "postgres". The CLI rejects unknown dialects instead.

Behavior Reference

Type Inference

Each value is classified in this order. The first match wins.

Detected as Rule
Null Empty value or the text null (case-insensitive)
Boolean true or false (case-insensitive)
Integer Parses as a 64-bit integer
Float Parses as a 64-bit float
UUID 36 characters in 8-4-4-4-12 hexadecimal form
Date YYYY-MM-DD
Timestamp YYYY-MM-DD followed by T or a space and a time (at least 19 characters)
Text Everything else

SQL Type Mapping

Detected as PostgreSQL MySQL SQLite
Integer BIGINT BIGINT INTEGER
Float DOUBLE PRECISION DOUBLE REAL
Boolean BOOLEAN BOOLEAN INTEGER
UUID UUID VARCHAR(36) TEXT
Date DATE DATE TEXT
Timestamp TIMESTAMPTZ DATETIME TEXT
Text / Null TEXT TEXT TEXT

Primary Keys

Existing columns (--primary-key / primary_key) are marked NOT NULL and listed in a PRIMARY KEY (...) clause at the end of the table definition. Composite keys keep the column order you give.

Auto-increment id (--auto-id / auto_id) adds an id column as the first column of the table. Its definition depends on the dialect:

Dialect Generated id column
PostgreSQL "id" BIGSERIAL PRIMARY KEY
MySQL `id` BIGINT AUTO_INCREMENT PRIMARY KEY
SQLite "id" INTEGER PRIMARY KEY AUTOINCREMENT

LICENSE

This project is licensed under the Apache License 2.0

Author

Created and maintained by cjggarcia.dev

Metadata

Release files for beaver-box 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for beaver-box 1.1.0
File Size Uploaded
beaver_box-1.1.0.tar.gz 58.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for beaver-box 1.1.0
File Interpreter ABI Platform
beaver_box-1.1.0-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
beaver_box-1.1.0-cp38-abi3-manylinux_2_34_x86_64.whl CPython 3.8 abi3 Linux glibc 2.34+ x86-64 Details

Total release size: 1.2 MB

Release files / beaver_box-1.1.0.tar.gz

Download URL beaver_box-1.1.0.tar.gz
Size 58.0 kB
Tags Source
SHA-256 checksum
How to use checksums
e58cfc5d37c1558cc6f2a2e3b1565f964bc29f1a2782c669bf25090023390766
BLAKE2b-256 checksum
How to use checksums
151a5b01aa560d7bc236675bc479bcea6cb17377ac67f1c7df04570fcb9cae55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / beaver_box-1.1.0-cp38-abi3-win_amd64.whl

Download URL beaver_box-1.1.0-cp38-abi3-win_amd64.whl
Size 487.6 kB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
e20acee1e1cdc899e68b0b8b67801f537d06aee86505604aecbd0c95bdcaf0f2
BLAKE2b-256 checksum
How to use checksums
2f2675db8a600533feeeab1bc87acee12e590ac27c9b0a2c7c96b3d0dc543d81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release files / beaver_box-1.1.0-cp38-abi3-manylinux_2_34_x86_64.whl

Download URL beaver_box-1.1.0-cp38-abi3-manylinux_2_34_x86_64.whl
Size 667.3 kB
Tags CPython 3.8 Linux glibc 2.34+ x86-64 abi3
SHA-256 checksum
How to use checksums
6c1082307ab609fda7f8ce6929fa9e177905f69c53895928aececbeb0b8cb71b
BLAKE2b-256 checksum
How to use checksums
b1e057ee08b57a07d65cc2720e19a53f561bb312e24a54ba4c1ebeacab13904a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.15.0

Release history Release notifications | RSS feed

This release

1.1.0 This release

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page