PostgreSQL is a powerful, standards-compliant database — but it has its quirks.
One of those is how it handles boolean values, especially when exporting data in text format.
🧠 PostgreSQL Boolean Behavior: It’s Not What You Think
Internally, PostgreSQL stores boolean values efficiently using just 1 bit — as you’d expect.
But when you convert those values to text, say in a query or an export via COPY, things look… different:
SELECT true::text; -- returns 't'
SELECT false::text; -- returns 'f'
Yep — true becomes 't' and false becomes 'f'.
That’s PostgreSQL’s default behavior in text I/O — and it can cause subtle bugs when moving data between systems.
🗂️ COPY & Export Gotchas
When using COPY TO (or tools like psql, pg_dump, or airflow/dbt/pandas under the hood), PostgreSQL exports booleans as 't'/'f', not true/false.
So this:
COPY my_table TO '/tmp/export.csv' CSV HEADER;
…will export boolean columns like:
id,is_active
1,t
2,f
If your downstream tools expect true/false or 1/0, you’re in for a confusing time. 🌀
🧪 Summary: Storage vs Representation
| Layer | What PostgreSQL Actually Does |
|---|---|
| Internal storage | 1 bit (0 or 1) |
| Text casting | 't' / 'f' |
| COPY/psql export | 't' / 'f' |
| CSV readers | Often expect true/false or 1/0 |
💡 Real-World Tip
If you’re working with ETL pipelines (dbt, pandas, Airflow, etc.) and you see 't' and 'f' in your data:
✅ Don’t panic — it’s normal in PostgreSQL. ✅ Explicitly cast or transform booleans when exporting/importing. ✅ Document the expected format for downstream tools.
🧵 Closing Thought
PostgreSQL is amazing, but it doesn’t always behave like MySQL, BigQuery, or Pandas.
This tiny detail about booleans is a great example of why knowing your database’s I/O behaviors can save hours of debugging.
“It’s not a bug — it’s just PostgreSQL being PostgreSQL.”