Postgres Foreign-key constraints in non public schema - postgresql

I have a question regarding constraints on custom schemas.
My app creates a new/separate schema for each clients corresponding with clients' name (i.e .clienta, clientb,...). Some of the tables have a foreign-key constraints but, they don't work on schemas other than the default public schema. For example, let's say there is schema called clienta and it has projects and tasks tables, model Task has a belongsTo(models.Project) association (i.e projects table primary_key is a foreign_key for table tasks. The issue starts here: when trying to create a record in table tasks there comes an error saying foreign key violation error... Key (project_id)=(1) is not present in table "projects... even though projects table has the respective record with id = 1. I am wording if this is a limitation of sequelize library itself or am I missing something in the configs?
Sequelize config
"development": {
"database": "my_app",
"host": "127.0.0.1",
"dialect": "postgres",
"operatorsAliases": "Sequelize.Op",
"dialectOptions": {
"prependSearchPath": true
},
"define": {
"underscored": true
}
}
Example of create function:
models.Task.create({...args}, { searchPath: 'clienta' })
N.B Everything works as expected in public schema.

The sync method API lists two options relating to DB-schema:
options.schema - schema the table should be created in
options.searchPath - optional parameter to set searchPath (Postgresql)
When using schemas other than the default and an association between Models has been created (using for instance belongsTo), it is important to set the searchPath to hold the name of the schema of the target table. Following the explanation in search_path in postgresql, not specifying the searchPath will have the constraint referring to a table (if it exists) in the default schema (usually 'public').

Related

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

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

DevExpress not showing PostgreSQL foreign tables

I'm trying to connect to PostgreSQL through DevExpress. The connection is returning the tables correctly except for the foreign tables.
Here's how I am connecting to PostgreSQL:
public DataConnectionParametersBase GetDataConnectionParameters(string name)
{
return new PostgreSqlConnectionParameters("xxx.xxx.xxx.xxx", XXXX, "dbName", "postgres_user", "XXXXXXXXX");
}
This is working well and returning all tables. However, the foreign tables are not showing.
Any ideas, please?
Try to trick your tool by using a VIEW on top of the foreign table:
CREATE VIEW x AS
SELECT * FROM your_foreign_table;
Most likely DevExpress checks pg_class just for the standard tables and views and isn't aware of new types of objects like foreign tables. But that's just an assumption.

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.

Unable to create a table in new database

beginner at SQL here, specifically using PostgreSQL. I'm trying to do something for a class here, but I keep receiving an error message and I'm not sure why. I've created a new database called "games", and I'm trying to create a basic table. The code is below.
The error message I receive is, [0A000] ERROR: cross-database references are not implemented: "games.games_schema.player_data" Position: 14
I can make the table in the default DB with postgreSQL fine, but why am I having issues trying to specifically create this table within this new Database?
CREATE DATABASE games;
CREATE TABLE games.games_schema.Player_Data
(Player_ID int,
Player_Name VARCHAR(255),
Player_System VARCHAR(255));
I thought the way I have my create table statement set up, is telling the server to create a table at that location. (database --> DBschema --> table)
Thanks for any help.
You created the games database, but that does not create a games_schema within it. It'll only create the schema Public (unless the default template has been modified) The solution is to either create a "games_schema" in the "games" database, or create your DB objects in the public schema.
Option 1: Create a schema.
create schema games_schema;
create table games_schema.player_data( ... );
Option 2: Use the Public schema.
create table player_data( ... );
My choice would be option 1, as I never allow anything other than extensions and Postgres supplied objects in public.

How to handle "secondary" keys in Entity Framework

I'm evaluating using EF against an existing schema - the problem is that I can't work out how to set up associations between tables where the foreign key is NOT the primary key of the master table.
As an example, a foo may have many bars as defined like this (forgive the pseudocode):
table foo {
int foo\_id pk,
char(10) foo\_code,
...
}
table foobar {
int bar\_id pk,
char(10) bar\_foo\_code fk(foo.foo\_code),
...
}
What am I missing to be able to create the foo_foobar association, and hence a Bars navigation property on the Foo entity?
Linq to entities doesn't support Foreign Keys which don't point to the primary key of a table (see log message 3). Linq to entities will treat it as a normal field on a table. You won't be able to navigate to the entity it's linked to.
If you have an existing schema i'd recommend using the edm generator as this will create the EMDX file, code behind and even the view code (which can be very large). If your existing scheme is quite large Check out this post, which explains how to deal with large schemas.
When you run the EDM Generator you'll find out all the things that are not supported.
Looking at a previous EDMGen2.exe log we got the following types of messages back:
The data type 'sql_variant' is not
supported, the column 'ColumnName'
in table 'TableName' was
excluded.
The table/view 'tableName' does not
have a primary key defined. The key
has been inferred and the definition
was created as a read-only table/view
The relationship 'RelationshipName'
has columns that are not part of
the key of the table on the
primary side of the relationship
which is not supported, the
relationship was excluded.
We've also found that the Linq project actually crashed Visual Studio quite alot as the code file produced by EDM was well over 80 mb.