I'm new to postgreSQL and I have a simple question:
I'm trying to create a simple script that creates a DB so I can later call it like this:
psql -f createDB.sql
I want the script to call other scripts (separate ones for creating tables, adding constraints, functions etc), like this:
\i script1.sql
\i script2.sql
It works fine provided that createDB.sql is in the same dir.
But if I move script2 to a directory under the one with createDB, and modify the createDB so it looks like this:
\i script1.sql
\i somedir\script2.sql
I get an error:
psql:createDB.sql:2: somedir: Permission denied
I'm using Postgres Plus 8.3 for windows, default postgres user.
EDIT:
Silly me, unix slashes solved the problem.
Postgres started on Linux/Unix. I suspect that reversing the slash with fix it.
\i somedir/script2.sql
If you need to fully qualify something
\i c:/somedir/script2.sql
If that doesn't fix it, my next guess would be you need to escape the backslash.
\i somedir\\script2.sql
Have you tried using Unix style slashes (/ instead of \)?
\ is often an escape or command character, and may be the source of confusion. I have never had issues with this, but I also do not have Windows, so I cannot test it.
Additionally, the permissions may be based on the user running psql, or maybe the user executing the postmaster service, check that both have read to that file in that directory.
Try this, I work myself to do so
\i 'somedir\\script2.sql'
i did try this and its working in windows machine to run a sql file on a specific schema.
psql -h localhost -p 5432 -U username -d databasename -v schema=schemaname < e:\Table.sql
Related
I have a bunch of SQL scripts that create tables in the database. Each table is located in a separate file so that editing them is much easier.
I wanted to prepare a single SQL script that will create the full schema, create tables, insert test data and generate sequences for the tables.
I was able to do such thing for oracle database but I am having problems with postgres.
The thing is - I do not know how to run the table creating script from another script.
In oracle I do it using the following syntax:
##'path of the script related to the path of the currently running sql file'
And everything works like a charm.
In postgres I was trying to search for something alike and found this:
\ir 'relative path to the file'
Unfortunately when I run my main script I get the message:
No such file or directory.
The example call is here:
\ir './tables/map_user_groups.sql'
I use Postgres 9.3. I tried to run the script using psql:
psql -U postgres -h localhost -d postgres < "path to my main sql file"
The file executes fine except for the calling of those other scripts.
Does anybody know how to solve the problem ?
If something in the question is unclear - just let me know :)
Based on the answer It is possible to reference another SQL file from SQL script, on PostgreSQL, you can include another SQL's files just using the \i syntax. I just tested and is working good on PostgreSQL 9.6:
\i other_script.sql
SELECT * FROM table_1;
SELECT * FROM table_2;
By the #wildplasser comment:
psql -U postgres -h localhost -d postgres < "path to my main sql file"
From psql's perspective the main_sql file is just stdin, and stdin has no "filename". Use -f filename to submit a file with a name:
psql -U postgres -h localhost -d postgres -f filename.sql
How to run postgres sql script from another script?
Seems the same question as: How to import external sql scripts from a sql script in PostgreSQL?
I use Ruby to generate a bunch of SQL commands, and store this into a file.
I then login to my PostgreSQL database. Then I do something like:
\i /tmp/bla.sql
And this populates my database.
This all works fine as it is, no problem here.
I dislike the manual part where I have to use \i, though (because I need this to work in a cron job eventually, and I think commands like \i are only available when you are directly in the interactive psql prompt).
So my question now is:
Is it possible to use a psql command from the command line that directly will start to read in an external file?
You can directly use the psql command as shown below.
Works for me with Ubuntu and Mint. On Windows it should be quite the same...
psql -U user -d database -f filepath
Example:
psql -U postgres -d testdb -f /home/you/file.sql
For more information take a lock at the official documentation: http://www.postgresql.org/docs/current/static/app-psql.html
When you try to execute an sql file using cron, you will also need to set the environment - database name, password etc. This is a short shell script snippet that does it all
source /var/lib/pgsql/scripts/.pgenv
echo $PATH
psql << AAA
select current_date;
select sp_pg_myprocedure(current_date);
AAA
In .pgenv, you set the values such as
export PGPORT=<yourport>
export PGHOST=<yourhost>
export PGDATA=<yourdatadir>
Also have a .pgpass file so that the password is supplied.
http://www.postgresql.org/docs/current/static/libpq-pgpass.html
Replace the part where SELECT is being done with whatever you want to do, or do it as #Kuchi has shown.
I run scripts against my database like this...
psql -d myDataBase -a -f myInsertFile.sql
The only problem is I want to be able to specify in this command what schema to run the script against. I could call set search_path='my_schema_01' but the files are supposed to be portable. How can I do this?
You can create one file that contains the set schema ... statement and then include the actual file you want to run:
Create a file run_insert.sql:
set schema 'my_schema_01';
\i myInsertFile.sql
Then call this using:
psql -d myDataBase -a -f run_insert.sql
More universal way is to set search_path (should work in PostgreSQL 7.x and above):
SET search_path TO myschema;
Note that set schema myschema is an alias to above command that is not available in 8.x.
See also: http://www.postgresql.org/docs/9.3/static/ddl-schemas.html
Main Example
The example below will run myfile.sql on database mydatabase using schema myschema.
psql "dbname=mydatabase options=--search_path=myschema" -a -f myfile.sql
The way this works is the first argument to the psql command is the dbname argument. The docs mention a connection string can be provided.
If this parameter contains an = sign or starts with a valid URI prefix
(postgresql:// or postgres://), it is treated as a conninfo string
The dbname keyword specifies the database to connect to and the options keyword lets you specify command-line options to send to the server at connection startup. Those options are detailed in the server configuration chapter. The option we are using to select the schema is search_path.
Another Example
The example below will connect to host myhost on database mydatabase using schema myschema. The = special character must be url escaped with the escape sequence %3D.
psql postgres://myuser#myhost?options=--search_path%3Dmyschema
The PGOPTIONS environment variable may be used to achieve this in a flexible way.
In an Unix shell:
PGOPTIONS="--search_path=my_schema_01" psql -d myDataBase -a -f myInsertFile.sql
If there are several invocations in the script or sub-shells that need the same options, it's simpler to set PGOPTIONS only once and export it.
PGOPTIONS="--search_path=my_schema_01"
export PGOPTIONS
psql -d somebase
psql -d someotherbase
...
or invoke the top-level shell script with PGOPTIONS set from the outside
PGOPTIONS="--search_path=my_schema_01" ./my-upgrade-script.sh
In Windows CMD environment, set PGOPTIONS=value should work the same.
I'm using something like this and works very well:* :-)
(echo "set schema 'acme';" ; \
cat ~/git/soluvas-framework/schedule/src/main/resources/org/soluvas/schedule/tables_postgres.sql) \
| psql -Upostgres -hlocalhost quikdo_app_dev
Note: Linux/Mac/Bash only, though probably there's a way to do that in Windows/PowerShell too.
This works for me:
psql postgresql://myuser:password#myhost/my_db -f myInsertFile.sql
In my case, I wanted to add schema to a file dynamically so that whatever schema name user will provide from the cli, I will run sql file with that provided schema name.
For this, I replaced some text in the sql file. First I added {{schema}} in the file like this
CREATE OR REPLACE FUNCTION {{schema}}.usp_dailygaintablereportdata(
then replace {{schema}} dynamically with user provided schema name with the help of sed command
sed -i "s/{{schema}}/$pgSchemaName/" $filename
result=$(psql -U $user -h $host -p $port -d $dbName -f "$filename" 2>&1)
sed -i "s/$pgSchemaName/{{schema}}/" $filename
First replace is done, then target file is run and then again our replace is reverted back
I was facing similar problems trying to do some dat import on an intermediate schema (that later we move on to the final one). As we rely on things like extensions (for example PostGIS), the "run_insert" sql file did not fully solved the problem.
After a while, we've found that at least with Postgres 9.3 the solution is far easier... just create your SQL script always specifying the schema when refering to the table:
CREATE TABLE "my_schema"."my_table" (...);
COPY "my_schema"."my_table" (...) FROM stdin;
This way using psql -f xxxxx works perfectly, and you don't need to change search_paths nor use intermediate files (and won't hit extension schema problems).
this is my problem:
myname#ubuntu:~$ sudo su postgres -c "psql template1"
Password:
psql (9.1.6)
Type "help" for help.
template1=# \i /create.sql
/create.sql: Permission denied
I have this problem even when the file is on the Desktop.
when I copy the text of create.sql and paste it there it works.
using UBUNTU 12.10, postgresql 9.1
Thank you for the help.
If you work in windows , you just need to pass the entire path wrapped by a single quotation.
test-# \i 'D:\\person.sql' --- > note here double backslash not single
The problem is that you've launched psql as the user postgres and you haven't granted the postgres user permission to read the SQL file. You'll need to give it permission. The simplest way is to grant world read rights:
chmod a+r create.sql
You can change the default permissions assigned to files by altering your umask; search for more information. Some programs rather annoyingly ignore the umask and set restrictive file permissions anyway, so you always need to know how to grant permissions. See man chmod and man chown.
BTW, you're using a very convoluted method for launching psql as the postgres user. This'll do just fine:
sudo -u postgres psql template1
Note that /create.sql specifies a file named create.sql in root of the file system (/). I doubt this is what you intended.
You probably want to specify it as a relative path (without the leading /) if it's in your home directory, like:
template1=# \i create.sql
or if it's on the desktop and you've started psql in your home directory:
template1=# \i Desktop/create.sql
EDIT: A better solution is to move the SQL file to the tmp folder if you are on linux!
I ran into this same issue on Linux but the accepted solution was not sufficient in my case. I eventually realized that you need to make sure that EVERY folder in the path has the correct permissions.
For example if the home folder does not have the correct permissions it does not matter what permissions you give a file inside of the SQL folder.
/home/username/Documents/SQL
if you are facing same issue after putting quote then use forward slash for paths
I'm new to postgreSQL and I have a simple question:
I'm trying to create a simple script that creates a DB so I can later call it like this:
psql -f createDB.sql
I want the script to call other scripts (separate ones for creating tables, adding constraints, functions etc), like this:
\i script1.sql
\i script2.sql
It works fine provided that createDB.sql is in the same dir.
But if I move script2 to a directory under the one with createDB, and modify the createDB so it looks like this:
\i script1.sql
\i somedir\script2.sql
I get an error:
psql:createDB.sql:2: somedir: Permission denied
I'm using Postgres Plus 8.3 for windows, default postgres user.
EDIT:
Silly me, unix slashes solved the problem.
Postgres started on Linux/Unix. I suspect that reversing the slash with fix it.
\i somedir/script2.sql
If you need to fully qualify something
\i c:/somedir/script2.sql
If that doesn't fix it, my next guess would be you need to escape the backslash.
\i somedir\\script2.sql
Have you tried using Unix style slashes (/ instead of \)?
\ is often an escape or command character, and may be the source of confusion. I have never had issues with this, but I also do not have Windows, so I cannot test it.
Additionally, the permissions may be based on the user running psql, or maybe the user executing the postmaster service, check that both have read to that file in that directory.
Try this, I work myself to do so
\i 'somedir\\script2.sql'
i did try this and its working in windows machine to run a sql file on a specific schema.
psql -h localhost -p 5432 -U username -d databasename -v schema=schemaname < e:\Table.sql