Prisma client not marking property as null - prisma

I am using Prisma version 3.8.1. Prisma client does not mark the User.oauthData property as nullable in TS. Can someone help? Prisma schema and generated SQL files below:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "rhel-openssl-1.0.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Account {
id BigInt #id
createdAt DateTime #db.Timestamptz(3) #default(now())
updatedAt DateTime #db.Timestamptz(3) #updatedAt
name String
users User[]
}
model User {
id BigInt #id
createdAt DateTime #db.Timestamptz(3) #default(now())
updatedAt DateTime #db.Timestamptz(3) #updatedAt
accountId BigInt
account Account #relation(fields: [accountId], references: [id])
fullName String
email String
oauthData Json?
}
-- CreateTable
CREATE TABLE "Account" (
"id" BIGINT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
"name" TEXT NOT NULL,
CONSTRAINT "Account_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "User" (
"id" BIGINT NOT NULL,
"createdAt" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMPTZ(3) NOT NULL,
"accountId" BIGINT NOT NULL,
"fullName" TEXT NOT NULL,
"email" TEXT NOT NULL,
"oauthData" JSONB,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "User" ADD CONSTRAINT "User_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "Account"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
I am using Prisma version 3.8.1. Prisma client does not mark the User.oauthData property as nullable in TS. Can someone help? Prisma schema and generated SQL files below:

When working with JSONB fields, there are two types of null allowed: JSON null and DB null.
This is explained in more detail in the Prisma docs for working with JSON fields.
To avoid this ambiguity between the two types of null allowed by the database, we allow one of the following two values:
Prisma.DbNull: The value in the database is a NULL.
Prisma.JsonNull: value in the database contains a JSON value that is null.
This is what those two null values look like in the database (same schema as the one you shared):
prisma-script> select id, "oauthData" from "User"
+---------+-------------+
| id | oauthData |
|---------+-------------|
| 124124 | null |
| 1241241 | <null> |
+---------+-------------+
You can also see this in the generated type for the model User

Related

Prisma2 prisma introspect returning weird values for foreign keys

I have two tables, User and Relationship. The tables are used to store a parent child relationship. I am using Postgres
// schema.sql
CREATE TABLE "public"."Relationships" (
id SERIAL PRIMARY KEY NOT NULL,
parent_id INT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES "User" (id),
child_id INT NOT NULL,
FOREIGN KEY (child_id) REFERENCES "User" (id)
)
CREATE TABLE "public"."User" (
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(128) NOT NULL,
email VARCHAR(128) UNIQUE,
password VARCHAR(128) NOT NULL,
isChild BOOLEAN NOT NULL DEFAULT false
created_at TIMESTAMP NOT NULL DEFAULT NOW();
);
When I run npx prisma introspect the following is returned in the schema.prisma file.
// schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Relationships {
child_id Int
id Int #default(autoincrement()) #id
parent_id Int
User_Relationships_child_idToUser User #relation("Relationships_child_idToUser", fields: [child_id], references: [id])
User_Relationships_parent_idToUser User #relation("Relationships_parent_idToUser", fields: [parent_id], references: [id])
}
model User {
created_at DateTime #default(now())
email String? #unique
id Int #default(autoincrement()) #id
ischild Boolean #default(false)
name String?
password String
Relationships_Relationships_child_idToUser Relationships[] #relation("Relationships_child_idToUser")
Relationships_Relationships_parent_idToUser Relationships[] #relation("Relationships_parent_idToUser")
}
I dont understand what User_Relationships_child_idToUser and User_Relationships_parent_idToUser are and why they are not just the simple syntax that appears for foreign keys in the Prisma docs tutorial.
Prisma's introspection generates two fields for each foreign key:
the relation scalar field (basically the direct representation of the foreign key)
a relation field (annotated with the #relation attribute) – these are the fields that seem to confuse you. The reason they provide is such that you can work with the relations easily in the Prisma Client API.
You can find more info about this in the docs here.
Of course User_Relationships_parent_idToUser and User_Relationships_child_idToUser are not very nice names. You can manually adjust the schema after introspection and rename the relation fields to have friendlier names, e.g:
model Relationships {
child_id Int
id Int #default(autoincrement()) #id
parent_id Int
child User #relation("Relationships_child_idToUser", fields: [child_id], references: [id])
parent User #relation("Relationships_parent_idToUser", fields: [parent_id], references: [id])
}

Struggling to manually create relations with gorm / migrate

I have an sql structure like so:
CREATE TABLE resources (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ NOT NULL,
deleted_at TIMESTAMPTZ
);
CREATE TABLE tags (
name TEXT PRIMARY KEY
);
What sql do I need to write, how can I tell gorm that I want a Resource to have many Tags? This is what I have currently go-wise:
package models
import (
"github.com/jinzhu/gorm"
)
type Tag struct {
Name string `gorm:"PRIMARY_KEY"`
}
type Resource struct {
gorm.Model
Title string
Tags []Tag `gorm:""`
}
Note that I explicitly do not want to auto-migrate via gorm. I am using the migrate tool to handle migrations and want to specifically handle them manually, not with go.
To define a has many relationship, a foreign key must exist.
So for your case Tag should be:
type Tag struct {
gorm.Model
Name string `gorm:"PRIMARY_KEY"`
ResourceID int
}
and Resource:
type Resource struct {
gorm.Model
Title string
Tags []Tag `gorm:"foreignkey:ResourceID"`
}
And your sql structure should have that foreign key ResourceID column.
Not sure if you have already checked this but it contains more details in case you need them: https://gorm.io/docs/has_many.html#Foreign-Key

Use postgres table sequence instead of sharing hibernate_sequence

When I do anything with a table, it always show the error:
Hibernate: select nextval ('hibernate_sequence')
2019-07-20 16:15:44.877 WARN 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2019-07-20 16:15:44.877 ERROR 58376 --- [nio-9000-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
I DON'T want to use hibernate_sequence to share id sequence between tables, but want to define id seq for each table and use them respectively.
I use Spring Boot 2.1.6.RELEASE, Spring Data JPA (Hibernate 5.3.10.Final), and Postgres 11.2, and define the id field with BigSerial type and hope to use the id sequence of each table in respective entity class.
The demo repo is here: https://github.com/Redogame/share_hibernate_sequence
Create user table (use identity as table name because user is a Postgres reserved keyword).
By defining id with bigserial type, Postgres will create a identity_id_seq automatically, and I verified that identity_id_seq has been created successfully.
create table identity
(
id bigserial not null
constraint identity_pkey
primary key,
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null
constraint identity_identity_id_fk
references identity,
last_modified_date timestamp not null,
last_modified_by_id bigint not null
constraint identity_identity_id_fk_2
references identity,
version bigint not null
);
Specify a sequence generator to use this id sequence:
#Table(name = "identity")
public class UserEntity extends Auditable<Long> {
#Id
#SequenceGenerator(name="identity_id_seq", sequenceName = "identity_id_seq", initialValue=1, allocationSize=1)
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="identity_id_seq")
private Long id;
But it doesn't work. I also tried to config spring.jpa.hibernate.use-new-id-generator-mappings and spring.jpa.properties.hibernate.id.new_generator_mappings, but still not work.
spring:
jpa:
hibernate:
use-new-id-generator-mappings: false
properties:
hibernate:
id:
new_generator_mappings: false
I expect not to use hibernate_sequence, that is: don't execute select nextval ('hibernate_sequence') before/after any SQL statement.
Try the below steps
CREATE SEQUENCE IF NOT EXISTS manual_seq;
Change create table script
create table identity
(
id integer NOT NULL DEFAULT nextval('manual_seq'::regclass),
name varchar(255) not null
constraint identity_name_key
unique
constraint identity_name_check
check ((name)::text <> ''::text),
created_date timestamp not null,
created_by_id bigint not null,
last_modified_date timestamp not null,
last_modified_by_id bigint not null,
version bigint not null,
CONSTRAINT manual_seq_pkey PRIMARY KEY (id)
);
I removed the foreign key constraint for testing purposes.
Update the entity mapping
#Entity
#Table(name = "identity")
#JsonIgnoreProperties(ignoreUnknown = true)
public class UserEntity extends Auditable<Long> {
#Id
#SequenceGenerator(name="manual-seq", sequenceName = "manual_seq",allocationSize = 1)
#GeneratedValue(generator="manual-seq")
private Long id;
#Basic
#Column(name = "name", nullable = false)
private String name;
#MappedSuperclass
#JsonIgnoreProperties({"new", "createdDate", "createdById", "lastModifiedDate", "lastModifiedById", "version"})
abstract class Auditable<PK extends Serializable>{
#NotAudited
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
#NotAudited
#CreatedBy
private Long createdById;
#LastModifiedDate
#Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;
#LastModifiedBy
private Long lastModifiedById;
#NotAudited
#Version
private Long version;
Revert the spring.jpa.hibernate.use-new-id-generator-mappings
The issue was extending AbstractPersistable because of which database sequence was not getting used. Also, note I have removed the audit for testing purposes.
The same problem was happening to me. I explicitly set spring.jpa.properties.hibernate.id.new_generator_mappings=false but select nextval ('hibernate_sequence') was still run by Hibernate.
I found that when we use the #GeneratedValue annotation without setting a strategy, it defaults to AUTO, which means, Hibernate will try to generate the ID value using hibernate_sequence and then it wil fail because it doesn't exist in the database.
So, I made #GeneratedValue (strategy = GenerationType.IDENTITY) and tried again. In this case, the ID value was generated by my identity column in the database (the primary key that is automatically incremented) and not by hibernate_sequence.
create table users (id serial not null, name varchar(250), primary key (id));

PostgreSQL foreign key create error

I'm new to PostgreSQL and trying to create table with foreign keys.But I got error below.
create table User_Role
(
RoleId serial primary key not null,
RoleCode varchar(21),
Rolename varchar(30),
isActive bool
)
CREATE TABLE User_Account(
UserId serial primary key not null,
RoleId_ref int REFERENCES User_Role (RoleId) NULL,
Username text NULL,
Password text NULL,
IsActive bool NULL
)
CREATE TABLE User_Profile(
ProfileId serial primary key not null,
UserId_ref int REFERENCES User_Account (UserId) NULL,
RoleId_ref int REFERENCES User_Role (RoleId) NULL,
FirstName Text NULL,
LastName Text NULL,
Address Text NULL,
City varchar(100) NULL
)
first two table created successfully. But last table occur create error.
ERROR: column "roleid" referenced in foreign key constraint does not exist
SQL state: 42703
but I can't understand why.

Laravel 5.3 Eloquent transactions and foreign key restrictions

Am working on bigger project where we have multiple schemas in one Postgres DB. We have created foreign keys between schemas. Here is an example >
We have company schema and user schema. Company schema has company_users table which have foreign key restriction on user.users table
CREATE TABLE company.company_user
(
id serial NOT NULL,
company_id integer NOT NULL,
user_id integer NOT NULL,
created_at timestamp(0) without time zone,
updated_at timestamp(0) without time zone,
deleted_at timestamp(0) without time zone,
CONSTRAINT company_user_pkey PRIMARY KEY (id),
CONSTRAINT company_user_company_id_foreign FOREIGN KEY (company_id)
REFERENCES company.companies (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT company_user_user_id_foreign FOREIGN KEY (user_id)
REFERENCES "user".users (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
Following queries run in Postgres without issue
BEGIN;
insert into "db"."user"."users" (id,"surname", "firstname", "email", "position", "language_id", "is_super_admin", "updated_at", "created_at") values (156,'Mueller', 'Julianne', 'julianne.mueller1#example.org', 'Nuclear Power Reactor Operator', 41, false, '2017-01-13 12:35:10', '2017-01-13 12:35:10') returning "id";
insert into "db"."company"."company_user" ("company_id", "user_id", "updated_at", "created_at") values (4445, 156, '2017-01-13 12:35:10', '2017-01-13 12:35:10') returning "id";
COMMIT;
However if i perform same queries via Eloquent in Laravel
\DB::beginTransaction();
$user = new User(["surname" => 'Mueller',
"firstname" => 'Julianne',
"email" => 'julianne.mueller1#example.org',
"position" => 'Nuclear Power Reactor Operator',
"language_id" => 41,
"is_super_admin" => false]
);
if (!$user->save()) {
\DB::rollBack();
return false;
}
\Log::error($user->id);
$company_user = new CompanyUser([
"company_id" => 4445,
"user_id" => $user->id
]);
if (!$company_user->save()) {
\DB::rollBack();
return false;
}
\DB::commit();
is throwing folloing error (it seems that it cannot find id of user in the table)
PDOException: SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "company_user" violates foreign key constraint "company_user_user_id_foreign"
Would anyone can say why this is not working? \Log::error($user->id) is printing id of inserted user. I tried to print out queries from Laravel with DB listener, all queries are executed in correct order, but am still getting this error.
Ok so we found a solution. It seems that we need to start transaction for each of schemas separately + each foreign key that are referencing different schema than their own should be created as deferred.
Make sure CompanyUser has $fillable:
$fillable = ['user_id', 'company_id'];
Also, make sure there is a user with this ID is already in users table. Maybe you'll need to get rid of transaction.