Is there any way to create foreign key from different schemas? - postgresql

I have an application where I am separating data with schemas where I have one table common in all schemas. lets say I have one public schema which is an admin schema and other schemas such as a,b,c,...,etc which are user schema. And all schemas have one common table T and all users can create entries in this T table and there are some entries which can only be created by admin user and all other users will use that rows.
so how I will achieve this.
I have two onptions in my mind
I will create T table in every schema and when ever admin adds new entry I will add that in all other schemas.
I will create T table in public schema and will add foreign key from that schema in other schema.
note: Schemas are dynamic and they are created run time and I am using postgres, Nestjs and sequelize-typescript

Related

SymmetricDS replication configuration for different schemas PostgreSQL

I want to replicate other schemas rather than the public schema. I have configured the sym_trigger table for the different schema but it doesn't work cause there were no sym_* tables in that particular schema. Is there any way to configure the xxxx.properties file or just use this command
alter user {user name} set search_path to {schema name};
and configure the sym_* tables just like public schemas?
The SymmetricDS tables will reside in the schema that is the default schema when you log in. If you want to access non-SymmetricDS tables in different schemas, you need to specify the source_schema_name in sym_trigger.

Create Postgres FDW using the postgres super user yet have read only access to the remote schema

I am trying to create an FDW using the postgres super user credentials using the following steps -
My super user is postgres
CREATE SERVER testfdw
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '10.10.10.171', dbname 'testdb', port '5432', fetch_size '50000');
I have created a read only remote user called testdb_read_only_user on testdb and granted read only privileges to all tables and sequences and functions in there
I now create a user mapping for my local db super user postgres
CREATE USER MAPPING
FOR postgres
SERVER testfdw
OPTIONS (user 'testdb_read_only_user', password 'testpasswrd')
Then I run IMPORT FOREIGN SCHEMA public FROM SERVER testfdw INTO test_local_schema;
Now when I try to create a new foreign table into test_local_schema using the postrges super user, I am still able to create one, but the actual behaviour I expect is a permission denied error and my user mapping is based on the read only user I created on the Remote DB
Am I missing something here. Please guide.
The foreign schema test_local_schema is owned by postgres(Superuser) and PostgreSQL treating it as a local schema(on target) gives you option to create a new table, Now when you are creating a new foreign table in test_local_schema postgres will check below constraints
The name of the foreign table must be distinct from the name of any other foreign table, table, sequence, index, view, or materialized view in the same schema.
To create a foreign table, you must have USAGE(read) privilege on
the foreign server, as well as USAGE privilege on all column
types used in the table
CREATE privilege on the target schema.
As your user mapping has read-only user in source database you should be able to fetch data in order to create a foreign table in target database, however whenever you will update and insert new data it will give you error as testdb_read_only_user is not having any update/insert privileges.
https://www.postgresql.org/docs/9.5/sql-createforeigntable.html
https://www.postgresql.org/docs/9.5/sql-importforeignschema.html

Replacing schema name when sharing sql script with other 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.

Separate and restrict data access using schemas

I am an Oracle DBA, new to PostgreSQL. I have a requirement to separate some modules data, so that one module will not have access to read the data of another module.
I read about the use of schemas in PostgreSql which is somewhat different than the use of it in Oracle. However seems like it is recommended to use the method of different schemas for separation and management - just like in Oracle.
However, when I create 2 schemas - connected to the same database and same user - I can do a select from the other schema's table.
That is, for example, if I have schema A owning table a, and schema B owning table b, when I set the search path to schema B I can do a select on schema’s A table a without any problem.
I couldn't find a way to revoke this privilege from schema B.
The only I could find then to separate access to data, is using different roles, that is to create role A with schema A, and role B with schema B. then I can grant and revoke access from user B in order for it to see what I want from role's A tables.
Is this correct? Am I missing something?
if I have schema A owning table a
A schema does not "own" a table in Postgres - a user does. This is the same as in Oracle - the difference (and maybe where your confusion arises) is that in Oracle in a regular user can't create tables outside of a schema that has the same name as the user account.
So if user arthur creates a table in schema_a and one in schema_b, both tables are owned by arthur - not "the schema".
If you used different schemas/users in Oracle to separate data and to prevent access to the other user's tables, then you need two users and two schemas in Postgres as well.
The default search_path in Postgres is setup in a way, that (unqualified) tables are always first searched (and created) in a schema with the same name as the user running the statement.
So if you create two users and a schema with the user's name for each user, you pretty much have the same setup as in Oracle:
create user arthur with password 'foobar';
create schema arthur authorization arthur; --<< this is what Oracle does "automatically"
create user bob with password 'verysecret';
create schema bob authorization bob;
Now, if bob creates a table, that table is created in the schema bob and is owned by the user bob. User arthur has not privileges to access that table.
If you never need to share data between those users (or schemas), then you can create two databases, create two users and let both users create everything in the public schema of "their" database.

Oracle foreign data wrapper

I have master-slave architecture. On the slave I have an Oracle database with two schemas, e.g. TEST1 and TEST2.
I have all objects (e.g. EMPLOYEES) stored in schema TEST1, and user TEST1 (or admin) has given read only privileges on TEST1.EMPLOYEES to TEST2, so when I use TEST1.EMPLOYEES in a query on the Oracle database I can access its data.
How can I implement the same using Oracle foreign data wrapper in postgres 9.5 because I have credentials for TEST2 and not TEST1?
When I try to access the foreign table it give an error saying that TEST2.EMPLOYEES does not exist.
You can easily do that if you define the user mapping with the credentials of user TEST2 and the foreign table with the schema option, i.e.
CREATE FOREIGN TABLE ... OPTIONS (schema 'TEST1', table 'EMPLOYEES');