Code like song
Sometimes in Postgres you want to initialize a table by reading a bunch of data from stdin, like this:
psql "$database" -f init.sql < /usr/share/dict/american-english
using an init.sql
like this:
DROP TABLE IF EXISTS dictionary;
CREATE TABLE dictionary (id SERIAL PRIMARY KEY, word VARCHAR NOT NULL);
\copy dictionary (word) from stdin
CREATE UNIQUE INDEX idx_dictionary_word ON dictionary (word);
The problem is that with the -f
flag, psql
ignores its stdin and treats the file you name with -f
as if it were stdin. So running the above would add just one word to your database, spelled “CREATE UNIQUE INDEX …”.
The solution to this is to use \copy dictionary (word) from pstdin
instead. That tells psql
to copy from its real stdin rather than from the -f
file.
As far as I know there is no way to do this using COPY FROM
rather than \copy from
if you want COPY FROM
to appear inside a larger .sql
file. So this works:
psql "$database" -c "COPY dictionary (word) FROM STDIN" < /usr/share/dict/american-english
but this does not:
psql "$database" -f init.sql < /usr/share/dict/american-english
and neither does this:
psql "$database" -c '\i init.sql' < /usr/share/dict/american-english
But I’d love to be corrected if someone knows a way!
blog comments powered by Disqus Prev: Postgres LATERAL JOIN Next: Rails acts_as_list with Soft Delete