I have a schema called lake and when I run
select schema_name
from information_schema.schemata
lake is not in the results. I found out about this when an Amazon utility script started failing. All other schemas (including any I create now) show up there. I thought all schemas were supposed to be there?
All schemas are visible to superusers. For other users it depends on who created the schema and whether you have permissions on it.
Try altering the schema owner to be the same as the other schemas you can see. https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_SCHEMA.html
alter schema us_sales
owner to dwuser;
Related
Need to create a view based on these conditions:
There are several schemas and tables in the db
We will create a union from tables from certain schemas
If the schema don't exist we should skip that schema from our union
It is given that if schema exists the associated table definitely exists, no need to check that.
Query should not give error if any of the schema is not created.
At the time of running query any schema could be missing that is not known until query is run.
So far creating the view using unions is simple enough but I'm not able to figure out what is the best way to include that condition check for schema existence, I'm sorry if this is trivial or duplicate question, any advice or reference could be helpful.
Thanks,
CJ
In postgresql we can use if schema exists:
SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'name';
I know I can run this:
grant select on all tables in schema whatever to "my_dev_group";
but the way I've built our CI system - we use lots of different schemas, so the schema is only known at the time of running the tests - not when the script is written. Ie we run the same script against lots of different test schemas and we set the schema name at the start...
so I am trying to achieve the equivalent of the above grant statement - but to operate on the current schema - without any success.
ie all of these were spectacularly unsuccessful
grant select on all tables in schema current to "my_dev_group";
grant select on all tables in schema current_schema() to "my_dev_group";
grant select on all tables to "my_dev_group";
is it possible to do without going into the world of executing dynamic sql, which I'd prefer not to
SQL doesn't have a notion of a “current schema”. Consequently, there is no syntax to change the permissions of all tables in the current schema.
You could loop through all schemas in the search_path or all schemas in the database and run a GRANT statement for each one. Make sure to skip system schemas like information_schema and pg_catalog.
Alternatively, you could use the current_schema() function to retrieve the first existing schema on your search_path and change permissions for that schema.
As per the AWS documentation,
To run a Redshift Spectrum query, you need the following permissions:
Usage permission on the schema
Permission to create temporary tables in the current database
I have an External database, schema and a table created in that schema.
I created a new Redshift user to which I granted 'usage' privileges on the external schema:
grant usage on external_schema to new_user;
But I did not provided 'temp' privileges on external_database to my new_user.
Also, there are no default privileges, as I checked PG_DEFAULT_ACL using master user and there are no rows in it.
Can someone let me know why I am able to query the external table?
In Amazon Redshift, Database and Schema are different concepts. User objects (Redshift and external) are created in Schema and TEMP objects are created in "temp" schemas and are available at database level.
In some cases, where join between Spectrum tables and Redshift tables is applied, Redshift needs to create temporary tables and that's why it is mentioned in documentation to avoid any failure/error for users.
Here is what documentation says:
Grants the privilege to create temporary tables in the specified database. To run Amazon Redshift Spectrum queries, the database user must have permission to create temporary tables in the database.
Note
By default, users are granted permission to create temporary tables by their automatic membership in the PUBLIC group. To remove the privilege for any users to create temporary tables, revoke the TEMP permission from the PUBLIC group. Then explicitly grant the permission to create temporary tables to specific users or groups of users.
When collaborating with colleagues I need to change the schema name every time I receive a SQL script (Postgres).
I am only an ordinary user of a corporate database (no permissions to change anything). Also, we are not allowed to create tables in PUBLIC schema. However, we can use (read-only) all the tables from BASE schema.
It is cumbersome for the team of users, where everybody is creating SQL scripts (mostly only for creating tables), which need to be shared amongst others. Every user has its own schema.
Is it possible to change the script below, where I will share the script to another user without the need for the other user to find/replace the schema, in this case, user1?
DROP TABLE IF EXISTS user1.table1;
CREATE TABLE user1.table1 AS
SELECT * FROM base.table1;
You can set the default schema at the start of the script (similar to what pg_dump generates):
set search_path = user1;
DROP TABLE IF EXISTS table1;
CREATE TABLE table1 AS
SELECT * FROM base.table1;
Because the search path was change to contain user1 as the first schema, tables will be searched in that schema when dropping and creating. And because the search path does not include any other schema, no other schema will be consulted.
If you
However the default search_path is "$user", public which means that any unqualified table will be searched or created in a schema with the same name as the current user.
Caution
Note that a DROP TABLE will drop the table in the first schema found in that case. So if table1 doesn't exist in the user's schema, but in the public schema, it would be dropped from the public schema. So for your use-case setting the path to exactly one schema might be more secure.
I have a bit of a funny situation in Amazon Redshift where I have a user X who has grant select on all tables in schema public, but once a new table is created, this grant doesn't seem to apply to the new table. Is this normal behaviour? If yes, how does one deal with it such that the schema level grants are maintained. Thank you.
Executing the following command as super user (master):
alter default privileges
for user staging_user
in schema staging
grant select on tables
to reporting_user;
will allow reporting_user to select data from all future tables created by staging_user in schema staging.
In Redshift tables and views do not automatically inherit the permissions of their parent schema. Your newly created tables are only accessible to the user who created them, and the superuser.
In a recent patch to Redshift a new feature to grant default privileges was implemented that addresses this issue.
Alter Default Privileges
The following code snippet will grant select privileges only for all future tables in the sales schema to the sales_admin group. If you want this to apply to existing tables in a schema you will need to combine it with a second grant statement.
alter default privileges in schema sales grant select on tables to group sales_admin;
This is a normal behavior. Only the object owner/superuser have permission to use the object by default.
http://docs.aws.amazon.com/redshift/latest/dg/r_Privileges.html
You can add grant command to your create table statement and grant needed privileges for the user.
When we first spotted new tables not appearing in our reporting tool, I discovered a quick workaround is to re-execute the following SQL statement for the groups/users impacted:
ALTER DEFAULT PRIVILEGES IN SCHEMA <SCHEMANAME> GRANT SELECT ON TABLES TO GROUP <USER/GROUPNAME>;