Prisma #db.Time(x) - what is x? - prisma

After running the npx prisma introspect in the console, the startTime attribute was set to #db.Time(6) in my schema.prisma file.
model Table {
id String #id #default(uuid())
startTime DateTime #map("start_time") #db.Time(6)
}
What does x mean in #db.Time(x) in Prisma schema? Documentation link
P.S. I use PosgreSQL as database

The x is the precision to store in the time type which can be anything from 0-6. You can read more this here.

Related

What should I use as validation tool using NestJS and MongoDB?

Let's say, I am creating application using NestJS. I use MongoDB as a database and mongoose as ODM. So, NestJS has it's own way to validate data - ValidationPipe's. On the other side, there is mongoose built-in ways to validate data that being pushed into DB.
The question is - can I use only NestJS validation or do I need also second-check my data using mongoose validation tools?
Personally, I can't see why should I use additional layer of validation if I already have NestJS validation. But maybe there is best-practice or something?
Each database validates input data and emits an error if found. However, you must take into account your schema file. For instance, if you are using Prisma(It doesn't actually matter) and you have a User model like below
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
email String #unique
password String
name String
image String?
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
##map("user")
}
As you can see there is only one optional property "image". Whether you pass a value for image property or not, the database will insert the data as a row. On the other hand, the properties without "?" mark at the end of the type, will not be stored if you don't pass them and emit an error.
Therefore, if you modeled schema according to your business logic, you don't need to validate twice but only add an exception handling like the one below.
const user = await this.usersService.findOne('id...')
.catch((e) => new NotFoundException({ message: 'No user found.' }))

Use of #map and ##map for Prisma schema

I am new to Prisma and have been wondering what is the use of #map and ##map for Prisma schema? I have looked at their website: https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#map but still don't fully get the purpose of #map and ##map.
From what I can comprehend, if I have something like
lastName String #map("last_name") #db.VarChar(256)
it maps "last_name" to lastname? But I am not too sure when I will need this.
Thank you! Appreciate any help.
#map can be used to assign a different name to your columns names, for example if the column name for a table in your database is userLastName but you want to assign a different name (user_last_name) and access it with a different name in your generated PrismaClient you can use #map attribute for it.
model User {
id Int #id #default(autoincrement())
userLastName String #map("user_last_name")
}
#map does not rename the columns / fields in the database
#map does change the field names in the generated prisma client
On the other hand ##map is used to assign a different name to a model and not a particular field. So for example if a table name is UserDetails and you want to access it as user_details in the generated client you can use ##map attribute.
model UserDetails {
id Int #id #default(autoincrement())
name String
##map("users_details")
}
Maps a field name or enum value from the Prisma schema to a column or document field with a different name in the database
A use case could be people integrating existing database with prisma and want to use different naming conventions between database & prisma client.
For example, one might use snakecase for database column but want to use camelcase for prisma client, then they will do:
model User {
createdAt String #map("created_at")
}
Same thing with ##map, but just for table name.
Detailed guide from prisma:
https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/use-custom-model-and-field-names

Prisma generated types not updating

I use Prisma as an ORM and had to change remove some columns and add others. I've already updated the database with the new columns and recreated the prisma schema but the problem is that now every time I try to insert a new entry, I get this error:
Unknown arg "picture" in create.picture for type usersCreateInput. Did you mean "image"?
"picture" is one of the new columns and "image" is one of the deleted ones, it seems that the generated types are not being updated properly, cause one of the new columns is there (email_verified), but the other (picture) isn't.
type usersCreateInput {
name?: String | Null
email?: String | Null
email_verified?: DateTime | Null
image?: String | Null
mentor?: Boolean | Null
weekly_time?: Int | Null
journey?: String | Null
pronouns?: String | Null
occupation?: String | Null
description?: String | Null
created_at?: DateTime
updated_at?: DateTime
skills?: usersCreateskillsInput | List<String>
boards?: boardsCreateNestedOneWithoutUsersInput
}
These are exactly the steps I did:
Changed the init.sql file used by Docker
Recreated the DB based on the new init.sql
Deleted the existent schema, then npx prisma init
Run npx prisma db pull and npx prisma generate to recreate the schema based on the already existent database,and it's important to note that I checked the schema and it's correct:
model users {
id Int #id #default(autoincrement())
name String? #db.VarChar(255)
email String? #unique(map: "email") #db.VarChar(255)
email_verified Boolean?
picture String?
mentor Boolean?
skills String[]
weekly_time Int?
journey String? #db.VarChar(255)
pronouns String? #db.VarChar(255)
occupation String?
description String? #db.VarChar(255)
created_at DateTime #default(now()) #db.Timestamptz(6)
updated_at DateTime #default(now()) #db.Timestamptz(6)
boards boards?
sessions sessions[]
}
Is there a way to completely reset prisma? I've also tried to remove node_modules and install everything again but it didn't solve.
If you ever run into a problem, where you think TypeScript is not working properly, you can always try to restart TypeScipt language server by pressing Ctrl+Shift+P and typing >Restart TS server. Make sure to navigate to a .ts file first!
This way you don't have to re-open VSCode.
I had the same problem. The solution was to run the command npm i to delete the current Prisma Client (no need to delete node_modules), and then run npx prisma generate to re-create a new Prisma Client.
Hereafter I still had an error when trying to query the new column, but then the solution was closing and re-opening the editor, in my case VS Code.

Postgres NestJS Prisma migration - Database error code: 23502 column of relation contains null values

I updated my Prisma ORM database model by adding two more fields 'ahash' and 'sAddress' to the 'invitation' table.
The table already contains 6 rows of data.
When I try to migrate the new changes to the Postgresql database, I get the error Database error code: 23502. ERROR: column "aHash" of relation "Invitation" contains null values.
How do I cater for the null values and migrate the model updates smoothly onto the database?
Give me a Step by step account please. I'm new to Prisma migration.
Thanks in advance!
The Prisma invitation model looks like below.
model Invitation {
id String #id #db.Uuid
workId String #db.Uuid
work Work #relation(fields: [workId], references: [id])
status RequestStatus
coId String #db.Uuid
oSignature String
note String
aHash String
sAddress String
createdAt DateTime
respondedAt DateTime
}
The problem here is that ahash and sAddress are both mandatory fields. However, they do not exist for the 6 existing rows/records in your database.
If you want to add new columns to an existing database without causing data loss you need to make sure the new columns/field are optional. This can be done in Prisma by marking the type of the field with a ?.
If you need the field to be mandatory, you could do it in three steps:
Create the new ahash and sAddress fields as optional first in your prisma schema and run a migration.
Run a script to update all existing records, so that they have a value for the ahash and sAddress fields.
Mark both fields as mandatory in your Prisma schema and run a migration.
In step 3, you will no longer get the error because none of the records contain a null value for the ahash and sAddress fields.

How to manage GetDate() with Entity Framework

I have a column like this in 1 of my database tables
DateCreated, datetime, default(GetDate()), not null
I am trying to use the Entity Framework to do an insert on this table like this...
PlaygroundEntities context = new PlaygroundEntities();
Person p = new Person
{
Status = PersonStatus.Alive,
BirthDate = new DateTime(1982,3,18),
Name = "Joe Smith"
};
context.AddToPeople(p);
context.SaveChanges();
When i run this code i get the following error
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.\r\nThe statement has been terminated.
So i tried setting the StoreGeneratedPattern to computed... same thing, then identity... same thing. Any ideas?
You have to manually edit the edmx xml and set your SSDL StoreGeneratedPattern attributes to identity or computed. But whenever you update your edmx via the designer your changes will get overwritten.
This is a known issue. Please see the following links for more details:
Microsoft Connect Ticket
Using a GUID as an EntityKey in Entity Framework 4
I had the same problem! For me it works like this:
Database MS SQL Server express:
[RowTime] [datetime2](7) NOT NULL
ALTER TABLE [dbo].[Table_1] ADD CONSTRAINT [DF_Table_1_RowTime] DEFAULT (getdate()) FOR [RowTime]
GO
Then I import the table from database to my Entities model.
Entities will not realise the default value!
So, you have to set the StoreGeneratedPattern of the column to Computed.
Then Entities will not put there any default value any more.
Combination of:
datetime2,
NOT NULL,
StoreGeneratedPattern=Computed
Works for me!
Changing type of DateCreated to datetime2 might solve the problem.
datetime 2007-05-08 12:35:29.123
datetime2 2007-05-08 12:35:29. 12345
Ref: http://technet.microsoft.com/en-us/library/bb677335.aspx67
Here is a working workaround:
1) Change the column to datetime2 as mentioned elsewhere. This fixes the conversion error.
2) Add a trigger that sets DateCreated to getdate();
CREATE TRIGGER [TR_AS_ChangeTime] ON [AS_ApplicationSession]
AFTER INSERT,UPDATE AS
BEGIN
SET NOCOUNT ON;
UPDATE AS_ApplicationSession
SET AS_ChangeTime = getdate()
WHERE AS_Id IN(SELECT AS_ID FROM INSERTED)
END
3) If neccessary, set
p.DateCreated = DateTime.MinValue;
just to initialize it.
4) If you need the DateCreated from the database, add
context.Refresh(System.Data.Objects.RefreshMode.StoreWins, p);
just after
context.SaveChanges();
Focusing on the fact that I do not want change the database, since it is an application problem and I expect them to solve this problem one day, my solution (that is totally possible in my case) is to create a partial class of the model to correct the problem on constructor:
public partial class Log
{
public Log()
{
this.Date = DateTime.Now;
}
}
This works for me because:
I create the model on the moment I send it to database.
I use CLOUD for these services, the datetime must be the same in both Application and Database servers!
Don't forget that the namespace needs to match the Model namespace or partial should not list properties (and should no be partial as well ;])!