Use of #map and ##map for Prisma schema - prisma

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

Related

Does Prisma support composite keys with one of the attribute being NULL for PostgreSQL?

In PostgreSQL you can make a table with 2 columns as the composite key of that table, with one of them being NULL-able. I was just wondering how I can achieve this with Prisma.
In the current version of Prisma that I have (3.14.0), Prisma does allow composite key using ##id([column1,column2]), but only if those two columns are mandatory.
No, Prisma doesn't support composite keys with optional columns. ID Definitions are required.
Example:
This would work
model Post {
title String
content String
##id([title, content])
}
But this wouldn't as column content is defined as optional
model Post {
title String
content String?
##id([title, content])
}
You can create a Feature Request here to support allowing nullable columns in composite id.

Is it possible to access metadata about the prisma model?

Let's say I have a model in my schema.prisma file:
model Post {
id Int #id #default(autoincrement())
author User #relation(fields: [authorId], references: [id])
authorId Int
}
Having a variable called model in my server containing a model name
const model: string = [model name generated dynamically]
Using this string I want to know every information about this model. For example if this variable model happens to be Post, I want to know that it has fields id, author, authorId and also information about each field separately, like in the case of author which field in which model does it reference, in this example the model User the field id.
I'm aware that prisma generates a type for each model and that way maybe I can access the fields that way but that't not enough for me, I want information about each fields as well.
I search the prisma docs, also googled something like 'get meta information about model in prisma2' but I didn't find any solution. Is there a way to achieve this?
Yes, you can get all the metadata for your entire schema in the following manner:
const prisma = new PrismaClient()
// #ts-ignore
console.log(prisma._dmmf)
This will give you all the details for the models and relations. The reason this is not documented is that this is highly experimental and will change with releases, which is why it's used for internal purposes only.

How to map a navigational property to a table where it isn't a key column?

I have an Entity like:
User
Id
Username
public virtual List<String> CountryNames { get;set; }
And it has a property for CountryNames as seen above, and this is linked to another table but it isn't linked on a key column.
The CountryNames property should get all UserCountry rows that have the Username.
UserCountry
Id
CountrName
Username
How can I configure the User model to do this?
I realize this is bad design, I'm not looking for schema design advise at this point as it is out of my hands.
I'm using EF6.

How to let ebean not generate any value for the ID?

I'm using Ebean, and define such a model:
#Entity
#Table(name = "users")
public class User extends Model {
#Id
public String id;
public String email;
public String name;
}
You can see the field id is String, and has a #Id annotation.
Now I save it:
User user = new User();
user.id = "abc";
user.email = "a#a.com";
Ebean.save(user);
But when I saved it, I found the value of it's id is: 1, not abc I specified.
I checked the sql, found the table generate:
create table users (
id varchar(255) not null,
email varchar(255),
name varchar(255),
constraint pk_users primary key (id))
;
create sequence users_seq;
You can see there is a seq users_seq which has been used when inserting a user.
How to define the model or how to configure Ebean to let it not do anything to the #Id field? Just let it use my specified value?
===========
UPDATE
Sorry, guys, I found this strange behavior is because of my mistake!
Yes, I use it with playframework 1, and I tried to create a play-ebean module for myself. But there is something wrong: When I save a model, I cleared the id value by mistake!
So the assigned value abc is missing, then Ebean will try to use a seq to get a new value for it.
Thanks for all you help, and sorry again, I will be more careful when I ask question next time.
Isn't it better idea to create another unique field and use it optionally ie. String userCode or something?
Play with Ebean uses auto incrementation of Id's to make sure the Id is unique so I'd personally didn't change that as all docs assumes that id of model is some numeric kind.
You can thought use Play's routes to find user by its string-id and still use Long id to perform basic operations.
(I'm writing in Play's context as I assume that you ask in it ;) )
You need to extend GenericModel instead of Model if you want to operate on your own #Id field. I am also talking in PlayFramework context.

JPA Relation or Secondary Table

I am reengineering one of my project with JPA which was initially on iBatis.
public class Entity{
//ids and other stuff
String locale;
String text;
}
I was storing locale and text into separate table, which can be achieved via secondary table in JPA.
I am not able to create secondary table with its own ids besides Join
id?
how can I achieve it? If possible then it raises the following
question:
how would I retrieve it back if I create an entity object with locale set to user settings
See,
http://en.wikibooks.org/wiki/Java_Persistence/Tables#Multiple_tables
Otherwise include your exact schema and model and issue.