- Learn
- PostgreSQL
- PostgreSQL connect to database (and the USE equivalent)
PostgreSQL connect to database (and the USE equivalent)
Switch databases with \c, connect with psql -d or a connection URI. There is no USE command in Postgres.
Quick answer
Already in psql, switching to another database:
Starting a new psql session against a database:
With a full connection string:
If you came here because USE mydb; gave you a syntax error, the next section is for you.
Why USE does not work in PostgreSQL
USE is a MySQL and SQL Server command. PostgreSQL has no equivalent statement, and it does not tell you that:
That is the whole error. There is no hint, no suggestion, and no mention of \c. PostgreSQL's parser has never heard of USE, so it fails at the first word and stops.
The equivalent is the psql meta-command \c:
\connect is a longer alias for the same command.
SET search_path is not the same as USE
This comes up constantly, and it is wrong often enough to be worth stating plainly.
That does not switch databases. search_path selects a schema, not a database, and the two are different things in PostgreSQL:
- A database is an isolated container. You connect to exactly one at a time, and a single connection cannot query across databases.
- A schema is a namespace inside a database.
publicis the default one. You can query across schemas freely within one connection.
MySQL blurs this: what MySQL calls a "database" behaves much more like a PostgreSQL schema, which is why USE feels like it should map onto SET search_path. It does not. If you are coming from MySQL and want the thing that behaves like USE, and you are working inside one database, SET search_path TO myschema; may genuinely be what you want. If you want a different database, you need \c and a new connection.
Coming from MySQL
| MySQL | PostgreSQL |
|---|---|
USE mydb; | \c mydb |
SHOW DATABASES; | \l |
SHOW TABLES; | \dt |
DESCRIBE mytable; | \d mytable |
SELECT DATABASE(); | SELECT current_database(); |
See PostgreSQL list databases for the SHOW DATABASES equivalent.
Switching databases with \c
The \c command takes several forms:
The - is a placeholder meaning "keep the current value".
\c opens a new connection
This is the part that matters and almost nobody mentions. \c does not switch context inside your session. It closes your connection and opens a new one, which means you get a completely new backend process.
Watch the backend PID change:
Different process. Anything tied to the old session is gone:
Temporary tables, prepared statements, and session settings set with SET all disappear. This happens even if you reconnect to the same database, because the reconnection is what destroys them, not the change of database.
If you need session state to survive, do not use \c.
The -reuse-previous trap
\c reuses your previous connection parameters, but only in the positional form. Pass a connection string and it does not:
It silently dropped the username and fell back to your operating system user. The documented behaviour is that parameters are re-used with the positional syntax but not when a conninfo string is given. Force it:
One more thing worth knowing: if \c fails in an interactive session, psql keeps your old connection. In a non-interactive script it does not, and the old connection is closed. A failed \c in a script leaves you with nothing.
Connecting from the shell with psql
The four flags you need:
| Flag | Meaning | Default |
|---|---|---|
-h | host | local Unix socket |
-p | port | 5432 |
-U | user | your OS username |
-d | database | same as the username |
Note that -d defaults to your username, not to postgres. That is why psql on its own often fails with database "yourname" does not exist.
Shorthand: the first bare argument is treated as the database name, so these are equivalent:
Connection strings and URIs
Every hosted Postgres provider hands you a connection URI, so it is worth knowing the format:
postgres:// works as a scheme too. Quote the whole thing, because ? and & mean something to your shell.
Useful variations:
Any special characters in a password must be percent-encoded. A password containing @ will otherwise be read as the start of the hostname.
URI parameters override flags
If you pass both, the connection string wins:
That connects on 5432, not 1234. The -p flag is silently ignored. This is documented behaviour, not a bug, and it is a good reason not to mix the two styles.
Passwords: PGPASSWORD, .pgpass, and prompts
By default psql prompts for a password. For scripts, you have three options.
PGPASSWORD works but the PostgreSQL docs specifically advise against it, because on many systems any user can read another process's environment via ps:
A password file is the recommended approach. Create ~/.pgpass:
Any field can be * to match anything. The file must not be readable by anyone else:
Get that wrong and psql ignores the file and tells you why:
A connection service file (~/.pg_service.conf) is worth knowing about if you juggle several servers, letting you connect with psql service=prod.
Environment variables
psql reads these when the equivalent flag is absent:
| Variable | Equivalent |
|---|---|
PGHOST | -h |
PGPORT | -p |
PGUSER | -U |
PGDATABASE | -d |
PGPASSWORD | (see above) |
PGPASSFILE | path to the password file |
PGSSLMODE | sslmode= |
Precedence, highest first: connection string parameters, then command-line flags, then environment variables, then built-in defaults.
Checking your connection with \conninfo
When you are not sure where you actually are:
On PostgreSQL 18 and later this prints a table:
Over a Unix socket, Host is replaced with Socket Directory.
On PostgreSQL 17 and earlier it is a single line:
The tabular format is new in PostgreSQL 18. Backend PID being listed there is handy for confirming the \c-makes-a-new-connection behaviour described above.
Connecting to Postgres in Docker
If Postgres runs in a container, the simplest path is to run psql inside it:
This uses the container's Unix socket, which is trusted, so it never asks for a password. That also means it is not a test of whether your password works.
From your host, connect normally, provided the port is published with -p 5432:5432:
From another container, use the service name as the host, not localhost:
Inside a container, localhost refers to that container. See Postgres Docker: The Complete 2026 Guide for the full setup.
Connecting to a remote server
Three things have to be true, and the error you get tells you which one is not.
- The server listens on an external address (
listen_addressesinpostgresql.conf, commonly'*'). pg_hba.confhas a rule permitting your client address, user, and database.- The port is reachable through any firewall.
Require encryption in transit:
sslmode=require encrypts but does not verify who you are talking to. For that, use verify-full with a CA certificate. On an untrusted network, require alone does not protect you from an active attacker.
Common connection errors
database "mydb" does not exist
The database is not there, or you are on the wrong server. List what exists with psql -l. If you ran bare psql and saw your own username in the message, that is -d defaulting to your username. See database does not exist.
role "myuser" does not exist
-U defaults to your OS username, so this usually means you did not pass -U at all. See PostgreSQL CREATE USER.
password authentication failed
Wrong password, or the wrong pg_hba.conf rule matched. Remember that connecting over a local socket often uses trust and never prompts, so a working socket connection proves nothing about your password. See invalid password.
Connection refused
Nothing is listening there. Wrong port, server not running, or it is not listening on that address. See connection refused.
No such file or directory
The socket-connection version of the same problem. The server is not running locally, or its socket is somewhere other than where psql is looking.
could not translate host name
DNS failed. Typo in the hostname, or inside Docker, a container name that is not on your network.
no password supplied
The server wants a password and psql had none to give and could not prompt. Common in scripts and cron. Use .pgpass.
psql: command not found
psql is not installed or not on your PATH. On macOS, brew install libpq and add its bin to your path. On Windows, add PostgreSQL's bin directory to PATH.
Quick reference
| Task | Command |
|---|---|
MySQL's USE mydb | \c mydb |
| Switch database | \c mydb |
| Switch database and user | \c mydb alice |
| Switch user only | \c - alice |
| Reconnect | \c |
| Connect from the shell | psql -h host -p 5432 -U user -d mydb |
| Connect with a URI | psql "postgresql://user:pass@host:5432/mydb" |
| Connect in Docker | docker exec -it postgres psql -U postgres -d mydb |
| Where am I connected? | \conninfo |
| Current database | SELECT current_database(); |
| Password without a prompt | ~/.pgpass, chmod 0600 |
| Require TLS | ?sslmode=require |
| Quit | \q |