How can I pass a mixed case table name to a script - pg-dump

I am trying to write a script which will do a pg_dump of a table and pass the name of the table as an argument
So I define a script called dumpTable:
table=$1
db=$2
file=$3.sql
pg_dump -a -t '\""$table"\"' -d $db -f $file"
But when I execute it:
dumpTable MyTable dbname mt
I get the error:
pg_dump: No matching tables were found
Is there a way I can pass my mixed case table name to a script for use in pg_dump?

Related

Is it possible to extract only tables starting with a specific name in pg_dump in Postgres?

Among the hundreds of tables in the postgres DB, only the structure dump of tables starting with a specific name is found.
Example
the name of the table
abc
abc_hello
abc_hi
def
def_hello
def_hi
If you think there is
I want to dump only tables starting with abc*.
pg_dump abc.txt -Fp -t abc* -s DBName
However, it was not recognized because the amount of tables was too large.
it answered,
pg_dump: error: too many command-line arguments (first is "DBName")
but this command works fine
pg_dump abc_hello.txt -Fp -t abc_hello -s DBName
How can I pick them out?
Your main mistake is that you didn't consider that * also is a special character for the shell. If you run
pg_dump -t abc* mydatabase
the shell will replace abc* with the names of all files in the current directory that start with abc, so that your command will actually be something like
pg_dump -t abcfile1 abcfile2 abcfile3 mydatabase
which is syntactically not correct and will make pg_dump complain.
You have to protect the asterisk from being expanded by the shell with single quotes:
pg_dump -t 'abc*' mydatabase
The other error in your command line is that you forgot the -f in -f abc.txt.

Update a PostgreSQL field from the content of a file

I have a file containing a value which should go into a field of a PostgreSQL table.
By searching a little, I found many answers, e.g. How can I update column values with the content of a file without interpreting it? or https://stackoverflow.com/a/14123513/6630397, with this kind of snippet, but it has to be run in a psql terminal:
\set content `cat /home/username/file.txt`
UPDATE table SET field = :'content' WHERE id=1;
It works, but is it possible to programmatically execute it in one shot, directly from a bash prompt, without manually entering the psql command line, e.g. something like:
$ psql -d postgres://postgres#localhost/mydatabase -c \
"UPDATE table SET field = :'the_file_content' WHERE id=1;"
?
There is also the -v argument that seems promising but I'm not successful when using it:
$ psql -d postgres://postgres#localhost/mydatabase \
-v content=`cat ${HOME}/file.txt` \
-c "UPDATE table SET field = :'content' WHERE id=1;"
I've got thousands of psql: warning: extra command-line argument where psql actually seems to "execute" each comma separated strings of the file as pg commands, where it shouldn't of course; the file content, which consists of a single line, must be treated as a whole.
Doc PostgreSQL 14:
https://www.postgresql.org/docs/current/app-psql.html
How about reading the file content into a variable first and then use it?
content=$(<integer_infile); psql -p 5434 -c "update table set field = $content where id = 1;"
content=$(<text_infile); psql -p 5434 -c "update table set field = '$content' where id = 1;"
This at least works for me if the file contains an integer or text including spaces on a single line.

Syntax error in "psql" , command not get executed

I am using timescaledb.
The doumentation I am following is Using PostgreSQL's COPY to migrate data from a csv file to timescale db. The name of csv file is test.csv.
I created the db named test , the name of table is test1. Table is a hypertable as per the timescaledb documentation.
The table's structure and csv files structure are the same.
While executing the following command in cmd I am not getting a result other than an addition of - symbol in the console command test-#
psql -d test -c "\COPY test1 FROM C:\Users\DEGEJOS\Downloads\test.csv CSV"
If I put ; after the command
psql -d test -c "\COPY test1 FROM C:\Users\DEGEJOS\Downloads\test.csv CSV"; I am getting a syntax error at Line 1.
How can I solve this error and insert data from csv file to db.?
You are trying to run psql with \COPY inside psql session, thus you get an error in the second call, since psql keyword does not exist in SQL. psql is an executable.
To follow the instructions from Timescale, you need to call the command directly in CMD. I.e, call:
psql -d test -c "\COPY test1 FROM C:\Users\DEGEJOS\Downloads\test.csv CSV"
If you are in C:\Users\DEGEJOS as in your screenshoot, it will look like:
C:\Users\DEGEJOS\psql -d test -c "\COPY test1 FROM C:\Users\DEGEJOS\Downloads\test.csv CSV"

How to split PSQL command lines over multiple lines?

I'm using a windows batch file to connect to postgres using psql. I'm issuing commands like this....
SET PGPASSWORD=postgres
psql -U postgres -d postgres -c "DROP USER IF EXISTS foo;"
This works fine for running one, short SQL command against the database. But I'm having trouble with two related issues
How to continue a single long SQL command over multiple lines, and
How to run multiple commands.
Example 1.....
psql -U postgres -d postgres -c "CREATE DATABASE foo
WITH OWNER = bar
ENCODING = 'UTF8'
TABLESPACE = mytabspace;"
Example 2.....
psql -U postgres -d postgres -c "
ALTER TABLE one ALTER COLUMN X TYPE INTEGER;
ALTER TABLE two ALTER COLUMN Y TYPE INTEGER;"
Neither of these will work as shown, I've done some googling and found some suggestions for doing this with linux, and have experimented with various carats, backslashes and underscores, but just don't seem to be able to split the commands across lines.
I'm aware of the -f option to run a file, but I'm trying to avoid that.
Any suggestions?
The line continuation character in batch is the ^. See this Q&A
So end the line with space+caret ^ and make sure the following line begins with a space.
You will also have to escape double quoted areas that span several lines with a caret for this to work.
Since the line is unquoted then for the batch parser you will also have to escape any special chararacters like <>|& also with a caret.
psql -U postgres -d postgres -c ^"CREATE DATABASE foo ^
WITH OWNER = bar ^
ENCODING = 'UTF8' ^
TABLESPACE = mytabspace;"
psql -U postgres -d postgres -c ^" ^
ALTER TABLE one ALTER COLUMN X TYPE INTEGER; ^
ALTER TABLE two ALTER COLUMN Y TYPE INTEGER;"

Creating a database dump for specific tables and entries Postgres

I have a database with hundreds of tables, what I need to do is export specified tables and insert statements for the data to one sql file.
The only statement I know can achieve this is
pg_dump -D -a -t zones_seq interway > /tmp/zones_seq.sql
Should I run this statement for each and every table or is there a way to run a similar statement to export all selected tables into one big sql big. The pg_dump above does not export the table schema only inserts, I need both
Any help will be appreciated.
Right from the manual: "Multiple tables can be selected by writing multiple -t switches"
So you need to list all of your tables
pg_dump --column-inserts -a -t zones_seq -t interway -t table_3 ... > /tmp/zones_seq.sql
Note that if you have several table with the same prefix (or suffix) you can also use wildcards to select them with the -t parameter:
"Also, the table parameter is interpreted as a pattern according to the same rules used by psql's \d commands"
If those specific tables match a particular pattern, you can use that with the -t option in pg_dump.
pg_dump -D -a -t zones_seq -t interway -t "<pattern>" -f /tmp/zones_seq.sql <DBNAME>
For example to dump tables which start with "test", you can use
pg_dump -D -a -t zones_seq -t interway -t "^test*" -f /tmp/zones_seq.sql <DBNAME>