SynthForge SynthForge SynthForge IO

Integration · SQL Server · T-SQL · Azure SQL

Generate SQL Server test data, with foreign keys intact

Multi-table fixtures that load with BULK INSERT and import_sqlserver.sql. Free web sessions.

Short answer

Design a multi-table schema in SynthForge, generate, and download the SQL Server export. You get import_sqlserver.sql (CREATE TABLE, BULK INSERT, then the foreign keys) and per-table CSVs. Every child row references a real parent by construction. Replace the <BUNDLE_DIR> placeholder with a directory the server can read, then run with sqlcmd. Everything lands in a synthforge_import schema.

Why generate rather than hand-roll

.NET teams, SSIS packages, and enterprise staging still need multi-table seed data that respects foreign keys. Hand-written INSERT scripts and half-empty CSVs waste more time than the features they unblock.

SynthForge sorts tables by dependency, generates parents first, and samples FKs from IDs that exist. The same schema exports to Postgres, MySQL, or Cockroach when your org runs mixed engines.

How to do it

1. Define the schema

Describe tables in plain English, build them in the visual editor, or paste CREATE TABLE DDL. AI forge and SQL import both produce multi-table schemas with single-column foreign keys.

2. Set cardinality (optional)

Use relationship ratios such as "1 to 4 orders per customer" instead of inventing every child row count. Parents generate first; child foreign keys are sampled from real parent IDs.

3. Generate and export SQL Server

Pick SQL Server as the SQL dialect (or include SQL export in formats). The download ZIP contains import_sqlserver.sql (CREATE TABLE, BULK INSERT loaders, then ALTER TABLE ADD CONSTRAINT for the foreign keys) and csv/<table>.csv data files. The script creates a synthforge_import schema and puts everything in it, so it will not collide with tables you already have. Identifiers use [brackets]; strings use NVARCHAR.

4. Fill in the CSV directory, then load

BULK INSERT opens the file as the SQL Server process, not as you, so a path relative to your shell means nothing to it. Rather than guess, the script ships a <BUNDLE_DIR> placeholder. Replace it with a directory the server can actually read, then run with sqlcmd (SQL Server 2017+ for FORMAT = 'CSV'). Forget this step and the script stops on the first load with the placeholder sitting in the error message, so you get told what to fix instead of a mystery.

bash
# Extract the ZIP somewhere the SQL Server process can read.
# On a local install that can be the bundle directory itself.
# In Docker it has to be a path inside the container (step 5).
cd /path/to/extracted-bundle
sed -i "s|<BUNDLE_DIR>|/path/to/extracted-bundle|g" import_sqlserver.sql

# Create a database (once), then import into it. Keep -d: the
# script builds a synthforge_import schema inside whichever
# database you connect to, and without -d that is master.
sqlcmd -S localhost -U sa -P 'YourStrong!Pass' -Q "CREATE DATABASE myapp_staging;"
sqlcmd -S localhost -U sa -P 'YourStrong!Pass' -d myapp_staging -b -i import_sqlserver.sql

# Loaders look like (after the substitution):
#   BULK INSERT [synthforge_import].[customers]
#   FROM '/path/to/extracted-bundle/csv/customers.csv'
#   WITH (FORMAT = 'CSV', FIRSTROW = 2, FIELDTERMINATOR = ',',
#         ROWTERMINATOR = '0x0a', TABLOCK);

5. Docker / Azure SQL notes

In Docker, copy the bundle into a path owned by the mssql user (for example /var/opt/mssql/load) - bind-mounting a 0700 host temp dir often fails with permission denied for uid 10001. Azure SQL Database does not support BULK INSERT from arbitrary client paths the same way; use bcp, Azure Blob + BULK INSERT FROM URL, or load via a jump box / container that can see the files.

bash
# Example: load into a local SQL Server container.
# Substitute the path the CONTAINER will see, not the host path.
sed -i "s|<BUNDLE_DIR>|/var/opt/mssql/load|g" import_sqlserver.sql

docker cp . sf-mssql:/var/opt/mssql/load
docker exec -u 0 sf-mssql chown -R mssql:mssql /var/opt/mssql/load
docker exec sf-mssql /opt/mssql-tools18/bin/sqlcmd \
  -S localhost -U sa -P 'YourStrong!Pass' -C \
  -d myapp_staging -b -i /var/opt/mssql/load/import_sqlserver.sql

6. (Optional) Agent path

With an API key and hosted MCP, agents can run description_to_dataset, download the ZIP, substitute <BUNDLE_DIR>, and load with the same import_sqlserver.sql. First API key includes 250 free credits; web sessions stay free.

text
# MCP endpoint: https://mcp.synthforge.io/mcp
# Auth: Authorization: Bearer sfk_live_…
# Docs: https://synthforge.io/docs/mcp

Frequently asked questions

Why does the script have a <BUNDLE_DIR> placeholder?
Because SQL Server reads the file path as the server process, not relative to your shell, so no path we could ship would be right on your machine. A placeholder makes that explicit: substitute it and the load works, forget it and the script fails immediately with the placeholder in the error. Run sqlcmd with -b, since without it sqlcmd exits 0 even when a load fails. The script is one batch, so a failure stops everything after it and the foreign keys never get added; fixing the path and re-running is safe, because the script drops and recreates its own tables.
Does SQL Server enforce the foreign keys?
Yes. SynthForge emits ALTER TABLE … ADD CONSTRAINT FOREIGN KEY after the data loads, and the data is referentially valid by construction: child keys are drawn from generated parent IDs.
FORMAT = 'CSV' - which SQL Server versions?
BULK INSERT … WITH (FORMAT = 'CSV') requires SQL Server 2017 or later (and compatible Azure SQL / Linux containers). Older engines need a format file or alternative loaders.
How large a dataset can I generate?
Up to 1,000,000 rows per table and 1,000,000 rows per dataset, plus a 200 MB cap on the generated download and per-account rate limits. The download cap is what binds on wide, text-heavy tables: 25 columns including free text reaches 200 MB at roughly 575,000 rows. A typical 15-column table generates 200,000 rows in about 12 seconds.
Can I use the same schema for Postgres or MySQL?
Yes. One schema exports to PostgreSQL, MySQL, SQLite, SQL Server, MariaDB, DuckDB, and CockroachDB, plus CSV, JSON, JSONL, and Parquet.
Does SynthForge use my real production data?
No. It generates greenfield data from the schema you provide. It does not ingest or de-identify a live database. For anonymizing real data, use tools like Tonic or NVIDIA NeMo.

Related

Ready to seed SQL Server staging?

Generate multi-table SQL Server data with real foreign keys, fill in one path, load with sqlcmd. No credit card for the web app.