PostgreSQL: permission denied for sequence posts_post_id_seq - postgresql

I'm new to PostgreSQL, and I'm testing a NodeJS/React app on cPanel.
I'm able to read data from the PostgresSQL database, but when I try to insert data into it I get the error "permission denied for sequence posts_post_id_seq". posts is the table name and post_id is the PK.
In node, I establish the connection to the database like so:
postgresql://${process.env.DB_USER_PROD}:${process.env.DB_PASSWORD_PROD}#${process.env.DB_HOST_PROD}/${process.env.DB_NAME_PROD}
I have checked every value in the string above and it is correct; as stated above, I can fetch data from Node using SELECT. DB_USER_PROD value is lemon_admin and in the screenshot below of phpPgAdmin I see that this user have all privileges
the server code for inserting is this:
app.post('/api/postsdb', async (req, res) => {
const {title, content, author} = req.body
try {
const postQuery = 'INSERT INTO posts(title, author, content) VALUES($1, $2, $3)'
await pool.query(postQuery, [title, author, content])
return res.send({status: 'ok', msg:'alrigth'})
} catch (error) {
return res.send({status: 'failed', msg: error.message})
}
})
This works locally with Postbird.
Since I am new to PG, it's very possible that Im missig something
I only have access to phpPgAdmin. I dont have SSH access.
How can I grant permission for this user to not only SELECT, but also to INSERT, UPDATE and DELETE? I have to do it from phpPgAdmin, please.
Thanks

To grant INSERT, UPDATE, DELETE use:
GRANT UPDATE, INSERT, DELETE ON posts TO username;
But it looks like table has some column which is fed by sequence. And user needs to have permission to use that sequence.
GRANT USAGE, SELECT ON SEQUENCE posts_post_id_seq TO username;
Also note that none of the above code has schema, do not forget to add or select before running it.

Related

Why can't one find the insert query in pg_stat_statements from sqlalchemy add and commit?

Is an INSERT INTO x... query ever issued from sqlalchemy?
The code to insert a few rows is:
session = Session(engine)
user1 = User(id=None, name='squidward', fullname='Squidward Tentacles')
user2 = User(...)
session.add(user1)
session.add(user2)
session.commit()
Then later on checking in postgres pg_stat_statements - there is not INSERT INTO users ... query.
It is certain that the correct instance is being checked.
Why is the query not showing up in pg_stat_statements?

RLS with Security Definer function returns error with no message, and no error in logs in Supabase / Postgresql

I have a table called user_roles with three columns: id, user_id, role.
With RLS disabled, I am able to update rows in this table with the call:
const { data, error } = await supabase
.from('user_roles')
.update({ role: role })
.eq('user_id', id);
Now I would like to add RLS so only admins can update the roles of users.
I am aware that this needs to be done in a security definer thanks to these two posts:
Role based authentication in Supabase
https://github.com/supabase/supabase/discussions/3328
So I have created an is_admin() security definer function as follows:
SELECT EXISTS (
SELECT 1
FROM user_roles
WHERE user_roles.user_id = _user_id
AND user_roles.role = 'admin'
);
$$ LANGUAGE sql SECURITY DEFINER;
and then I have a policy for updates with USING expression is_admin(uid())
However when I enable RLS and make my call I get the response:
error { message: '' }
There are no errors in my logs so I am unsure how to proceed.
Does anyone have any ideas of what could be wrong or what to investigate next? Many thanks
It seems the problem was because Update also does a Select in supabase so you need a policy for select too or specify { returning: "minimal"} in the update call
https://github.com/supabase/supabase/discussions/5097
in my case I set the Select policy to (uid() = user_id) OR is_admin(uid())

how can we check whether a table already exists or not, in typeorm?

postgresql, typeorm
how can we check whether a table already exists in a database before starting database operations on that table?
currently my code is like this, i check whether an item is present in database. But the problem with this approach is that, if its a fresh deployment, and if the tables are not present, then an exception is thrown.
const found = await this.userRepository.findOne(undefined); //<<< throws exception if tables not already created
if (found === undefined) {
const item: Items = this.userRepository.create({....});
}
so how can we add a check for a table's existance first, before doing database operations on it?
If you can use raw SQL queries for this, you can get the Entity Manager from the User Repository and run a query to check the information schema. Just replace the following snippet with your SCHEMA_NAME and TABLE_NAME.
const tableExists = (
await this.userRepository.manager.query(
`SELECT exists (
SELECT FROM information_schema.tables
WHERE table_schema = 'SCHEMA_NAME'
AND table_name = 'TABLE_NAME'
)`,
)
)[0].exists;
Adapted from this answer.

In .NET 5 why am I unable to access PostgreSQL tables in a custom schema?

We have a custom schema (config) in our DB where we have multiple tables declared and populated. In DataGrip and pgAdmin alike we're able to see the tables in the custom schema. The following query shows us tables in both the public schema as well as in the custom schema:
select table_schema, table_name
from information_schema.tables
where not table_schema='pg_catalog'
and not table_schema='information_schema';
In DataGrip we had to "show all schemas"; in pgAdmin, everything was visible right away, tables from both schemas.
However, in .NET code, when we run the same query, we only see the public tables.
await using var conn = new NpgsqlConnection(connString);
await conn.OpenAsync();
await using var cmd = new NpgsqlCommand(
#"select table_schema, table_name
from information_schema.tables
where not table_schema = 'pg_catalog'
and not table_schema = 'information_schema';", conn);
await using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync())
Console.WriteLine(reader.GetString(0) + "." + reader.GetString(1));
The connection string does include: ;SearchPath=config,public
All we're getting back from that code is tables in public.
We noticed that there is a hostname for the cluster and a hostname for the DB instance. We were using one (I think it was the instance) and tried using the other (cluster hostname) and suddenly the .NET code was able to see the config schema tables.

psycopg2 change schema does not work

I am writing a simple python prog to connect and display results from Postgres table this is on AWS RDS. I have table mytest in public schema.
connection = psycopg2.connect(dbname='some_test',
user='user1',
host='localhost',
password='userpwd',
port=postgres_port)
cursor = connection.cursor()
cursor.execute("SET SEARCH_PATH TO public;")
cursor.execute("SELECT * FROM mytest;")
But this throws an error
psycopg2.ProgrammingError: relation "mytest" does not exist
LINE 1: SELECT * FROM mytest;
Connection is successful and I can query other basetables like
SELECT table_name FROM information_schema.tables
It is just that I cannot change to any other schema. I googled and tried all kinds of SET SERACH_PATH and commit it and recreate cursor etc. but no use. I cannot query any other schema.
ALTER USER username SET search_path = schema1,schema2;
After setting this the query works fine!