SQL to YAML Converter
Turn seed rows into a fixture file. Each row becomes a mapping in a list, each column gets one type, and every value a YAML reader might misread comes back quoted.
To convert SQL to YAML, paste your INSERT statements above. Each row becomes one mapping in a YAML sequence, keyed by column name, with a type decided once per column. Values that a YAML parser would coerce into something else, dates and padded codes and the word no among them, are quoted so they survive. Nothing is uploaded.
Want to drop columns before you generate the file? Open the app
Fixtures, and the awkward gap between a database and a repository
The reason to convert SQL to YAML is almost always that the rows exist in one place and need to exist in another. A staging database has the reference data somebody spent a week getting right, and the test suite needs it as a fixture. Rails, Symfony, Go's testify helpers and most Python test setups all read YAML.
The second reason is review. A pull request that adds forty INSERT statements gets skimmed. A pull request that adds forty YAML mappings gets read, because the diff is legible and a reviewer can see that the third row has no owner.
Both uses share one requirement: the file has to load back as the same data. That is where most CSV-shaped converters fall over, and it is what the rest of this page is about.
Worked example
A regions table with the two hazards that matter:
INSERT INTO regions (region_code, region_name, opened_on, active, note) VALUES
('01', 'North Coast', '2019-03-04', TRUE, NULL),
('02', 'Lakeside', '2020-07-19', FALSE, 'seasonal');
And the YAML:
- region_code: '01'
region_name: North Coast
opened_on: '2019-03-04'
active: true
note: null
- region_code: '02'
region_name: Lakeside
opened_on: '2020-07-19'
active: false
note: seasonal
Two values are quoted and the rest are bare, and each decision is deliberate. '01' unquoted is the number 1, and your region codes stop matching. '2019-03-04' unquoted is a YAML 1.1 timestamp, so PyYAML hands the test suite a datetime object where the fixture said a string. North Coast needs no quotes and does not get any, because a file where everything is quoted is a file nobody wants to read.
The quoting rules, and why they look paranoid
YAML resolves bare words into types, and YAML 1.1 readers resolve more of them than anyone expects. The famous casualty is Norway: the country code is no, and unquoted that is the boolean false. The same trap catches yes, y, n, on, off and ~.
The second family is anything that reads as a number when it is not one. 01730 loses its zero. 1.10 becomes 1.1. 1e5 becomes 100000. A version string like 2.0 becomes a float and then prints back as 2.0 or 2, depending on the writer.
So the rule is per value, not per column: quote anything that some reader might resolve into a different type, leave everything else bare. That is why a country column can hold a bare `se` and a quoted `'no'` on adjacent lines. It looks inconsistent and it is exactly right.
Types, decided once per column
A column becomes numbers only when every value in it round trips exactly. 42 does. 275.00 does not, because writing it back gives 275.0. A column with one such value stays strings from top to bottom, which is the only way to avoid a list where some entries are numbers and some are strings under the same key.
SQL TRUE and FALSE become real YAML booleans. NULL becomes null, not an empty string, because in a config or a fixture that distinction is usually what decides whether a default applies.
The shape, and what to add yourself
The output is always a flat sequence of mappings: one list, one entry per row, keys in column order. That is the shape a fixture loader expects and the shape our YAML to CSV converter reads back into the same rows.
What it is not is a document with a top-level key wrapping the list, or entries grouped by one of the columns. Both are common and both are guesses, so neither is offered. Adding regions: above the list and indenting is a two-second edit; unpicking a wrong guess is not.
There is also no # Generated by comment in the output. A competing converter stamps one into every YAML file and every SQL script it writes, with no way to turn it off. Your fixture file is yours.
Frequently Asked Questions
Why is my date wrapped in quotes?
Because a bare 2019-03-04 is a YAML 1.1 timestamp, and PyYAML will hand your test a datetime object where the fixture said a string. Quoting keeps it a string. A competing converter emits these bare, on a page whose own FAQ claims it does not.
Why is one value in a column quoted and the next one bare?
Quoting is decided per value, from what that specific text would resolve to. In a country column, no is the boolean false in YAML 1.1 and has to be quoted, while se is unambiguous and stays bare. Quoting everything would be safe and would make the file unreadable.
Does NULL become null or an empty string?
A real YAML null. The database distinguished those and so does this, because in a fixture or a config that difference usually decides whether a default applies.
Why did my price column come out as strings?
Because at least one value does not round trip. 275.00 written back as a number is 275.0, a different string, so the whole column stays text rather than half the rows quietly changing. The rule is applied per column, never per cell.
Can I get a top-level key above the list?
Not as an option. The output is always a flat sequence of mappings, which is what fixture loaders expect and what our YAML to CSV tool reads back. Adding a wrapping key and indenting is a quick edit; guessing wrong about the shape is not.
Is there an attribution comment in the file?
No. Nothing is added to your output. Two of the free converters on this term stamp a generated-by line into every YAML and SQL file they write, and only one of them lets you turn it off.
Turn seed rows into a fixture
One mapping per row, one type per column, quotes exactly where a parser needs them.
Back to the converter