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.”