How can I adjust prisma scheme to 'autofil' - sql

I just started using prisma and was wondering whether you could perform an 'autofill'.
For instance: I have a leaderboard, and whenever I list down the teamID, the teamName column gets filled up automatically.
A piece of the schema is as follows.
model LeagueTable {
id Int #id #default(autoincrement())
competitionId Int
teamId Int
played Int
won Int
drawn Int
lost Int
points Int
goalsFor Int
goalsAgainst Int
goalDifference Int
tname String
competition Competitions #relation("competition-lt", fields: [competitionId], references: [id])
team Teams #relation("team", fields: [teamId], references: [id])
}
model Teams {
id Int #id #default(autoincrement())
name String #unique
matchesAsAway Fixtures[] #relation("awayTeam")
matchesAsHome Fixtures[] #relation("homeTeam")
leagueTable LeagueTable[] #relation("team")
}
I was thinking of adding a relation but at the same time I am trying to normalise the scheme as a possible.
Prisma Studio Leaguetable Preview
As you can see the tName column is empty, and I would need to fill it up manually. Is there a way to have it filled up when inserting the teamID

The only way to accomplish this in Prisma is to add another relation as you mentioned.
It might be possible with custom SQL triggers (like before insert), but you would be well outside the Prisma happy path.

Related

Prisma: Create or Connect Records in Explicit Many-to-Many Relations

In my Prisma Schema, I'm finding it difficult to undertand how to to create records in case of explicit many-to-many relations.
I have the following schema. Basically it represents Lists of Books. Users can Create Lists of Books.
A user can create a New list and then add books to this list along with their own notes. The Book Model is pure and contains standard book information.
The extra model is required because the user who is adding the book to the list can add his own notes about the book.
model List {
id Int #default(autoincrement()) #id
title String
slug String?
content String?
published Boolean #default(false)
author User? #relation(fields: [authorId], references: [id])
authorId Int?
books BooksInLists[]
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
}
model BooksInLists {
list List #relation(fields: [listId], references: [id])
listId Int // relation scalar field (used in the `#relation` attribute above)
book Book #relation(fields: [bookId], references: [id])
bookId Int // relation scalar field (used in the `#relation` attribute above)
##id([listId, bookId])
adder User? #relation(fields: [adderId], references: [id])
adderId Int?
notes String?
}
model Book {
id Int #id #default(autoincrement())
name String
lists BooksInLists[]
curator User? #relation(fields: [curatorId], references: [id])
curatorId Int?
bookDescription String?
}
model User {
id Int #default(autoincrement()) #id
name String?
email String? #unique
lists List[]
books Book[]
booksinlists BooksInLists[]
##map(name: "users")
}
The queries that I want to be able to do.
While updating a list, I should be able to add a new book to the list. This should create the new book, and also allow me to add a new record in BooksInLists model along with the 'notes' field.
While updating a list, I should be able to add/connect an existing book to the list. This will allow me to add a new record in BooksInLists model along with the 'notes' field.
It will be something like that:
prisma.booksInLists.create({
data: {
list: {
connect: {
id: 99
},
},
book: {
create: {
name: 'Young Lions'
}
}
}
})
However I see flaws in database schema. Model BooksInLists connects Books and List, so you don't need adder relation. In turn in Book model you shouldn't add curator relation because it's many to many relation. You have to use junction table usersBooks that connects User and Book tables.

Tables design for a simple messaging system

I got a simple message system where every message has one sender and always exact one receiver which is never the sender. So my design is like follow:
create table user
{
PersonID int,
Name varchar(255)
}
create table message
{
MessageID int,
FromPersonID int,
ToPersonID int,
Message varchar(160)
}
To get all messages of a given PersonID I write:
SELECT MessageID FROM message WHERE PersonID=FromPersonID OR PersonID=ToPersonID
Now I got two question:
Is this the proper (and fasted) way to design that relation.
How is this relation described in a Database Diagram?
Yup, that's pretty much the textbook way to do it.
Not sure what you mean by "how is it described in a diagram". In a diagram you would draw two boxes, one for each table. Then there would be two lines connecting User and Message, one labeled "from" and the other labeled "to". The exact shape of the boxes and appearance of the lines depends on what diagramming convention you are using.
You can normalize it according to your query.
for the query
SELECT MessageID FROM message WHERE PersonID=FromPersonID OR PersonID=ToPersonID
you can create a normalized structure
create table user
{
PersonID int,
Name varchar(255)
}
create table message_meta
{
FromPersonID int,
ToPersonID int,
}
create table message_data
{
MessageID int,
Message varchar(160)
}
and fire a query like
SELECT MessageID FROM message_meta WHERE PersonID=FromPersonID OR PersonID=ToPersonID
This will be more efficient. TC

What should I make the type of a "marital status" field?

I have a field in my table "marital status" , the user has to choose (radiobutton) if he's (married, divorced, single, voeuf)
What should I make the type of this field?
Is there a boolean type?
marital status doesn't sound like a boolean anyway. It sounds like an enumeration. A boolean would be married (Y/N), although I think in this day and age you might want to be able to store multiple kinds of relationships in there, and you specified yourself that you need to store 'devorced' as well, so a boolean is out of the question.
So I'd recommend making a table named MaritalStatus, having an ID and a description. Store the various states in there, and make a foreign key to MaritalStatusID in your table.
Make it an INT field , Create another table in your database something like
CREATE TABLE dbo.MaritalStatus
(
M_ID INT PRIMARY KEY NOT NULL,
M_Status NVARCHAR(20)
)
GO
INSERT INTO dbo.MaritalStatus
VALUES
(1, 'Single'),(2,'Married'),(3,'Divorced'),
(4,'Widowed'),(5,'Other'),(6,'Prefer Not to say').... bla bla
Now in your Table in "Marital Status" field refer to a user Marital Status using INT values from dbo.MaritalStatus table's "M_ID".
Boolean or in SQL bit datatype is best when you have a situation where something can be TRUE or NOT TRUE, for someone's Marital Status there can be more than two possible values therefore you should create a separate table for all the possible Marital Status and use Foreign key constraint.
The boolean equivalent for T-SQL is bit.
Though, it seems like you want more than a yes/no answer. In this case use an int and then convert the int to an enum.
Edit: Dukeling removed the C# tag in an edit, so I am not sure how relevant this part is anymore /Edit
The enum:
enum MaritalStatus
{
Single,
Married,
Divorced,
...
}
The int from DB:
int maritalStatusFromDB = //value from DB
Convert int to enum:
MaritalStatus maritalStatus = (MaritalStatus)maritalStatusFromDB;
Be aware that your database may contain int values that are not defined in your enum, such as 10. You can check whether maritalStatusFromDB is a valid MaritalStatus as follows:
bool isValid = Enum.IsDefined(typeof(MaritalStatus), maritalStatusFromDB);
if( isValid == false )
{
//handle appropriately
}

Simulating Inheritance in Database

I am working on a database, using Sql Server 2012. In our data model we have a type of User, with basic login information, name, address, etc, etc. Some of these users will be Technicians, who have all the same properties as a User, but some other properties like Route, Ship To Location, etc.
My question is, in designing a database, how does one simulate this situation. I have thought of 2 options.
Have a foreign key in the Technician table to the PK of the User database to link them up. My worry with this one is how will I know if a user is a technician, I would have to run a query on the technicians table each time a user logs in.
Have a field in User table link up with the PK of the Technician database, and if this field is null, or -1 or whatever I know this user is not a technician. I dont see any immediate problems with this one, but I am no expert at database design.
Do either of these have an advantage, and if so, why? Currently I have 2 different tables with two completely different id's, and they are not linked in any way, which I am now facing problems because of.
lets say you have 3 different sub class type of Class user. you can have a column in User table to identify the subclass Type. for example UserTypeID. if possible values are too many you can create new table to store these userTypes.
UserTypeID
1=Technician
2=Mechanic
3=Accounttant
Edit1
UserTypeID will be exist in all sub class entities.
Also from the other comments I feel lot concerns about getting data out of sync w/o explicit RI constraint. Just wanted to make sure that this column value should not be coming from app code or user instead the sql API inserting record should find out the right value based on which sub class entity is getting the insert record.
For example Pr_InsertUser API insert new technician. This insert API first finds out why I the UserTypeId for technician and insert record in to class user and get userid. Then passes the userId and UserTypeId to subclass technician an call another private sql API Pr_Insert_Technician to insert more attributes.
So the point I am trying to make is as SQL does not support explicit FK from multiple tables to single table that should be taken care in SQL API.
Declare #user Table
(
userid int
,UserTypeID Tinyint
,username sysname
,userAddress sysname
)
Declare #Technician Table
(
userid int
,UserTypeID Tinyint
,attr1 sysname
,attr2 sysname
)
Declare #Mechanic Table
(
userid int
,UserTypeID Tinyint
,attr3 sysname
,attr4 sysname
)
Declare #Accounttant Table
(
userid int
,UserTypeID Tinyint
,attr2 sysname
,attr4 sysname
)
You may want to familiarize yourself with the way ORM's do it.
Even if you don't use an ORM. It will lay out some of the options.
http://nhibernate.info/doc/nh/en/#inheritance
http://ayende.com/blog/3941/nhibernate-mapping-inheritance

JPA-how to Add record to master table and child table?

I am having two tables One is a Master table called TRANSACTION and second is record of the transaction this table is called TRANSACTION_RECORD.
TRANSACTION
CREATE TABLE `e3_transaction` (
`transactionid` bigint(20),
`transactiontype` varchar(10),
`transactionstatus` varchar(10),
PRIMARY KEY (`transactionid`)
);
TRANSACTION_RECORD
CREATE TABLE `e3_as2805msg4` (
`transectionid` bigint(20),
`messageType` int(4),
`cardAcceptorName` varchar(40),
`adNational` varchar(1000),
`adPrivate` varchar(1000),
KEY `transectionidFK` (`transectionid`),
CONSTRAINT `transectionidFK` FOREIGN KEY (`transectionid`) REFERENCES `e3_transaction` (`transactionid`)
);
It will have one to one mapping between Transaction and transaction record. It means one transaction can have only one record. I have kept this table separately for some reasons. So my class will look like this:
#Entity
#Table(name = "e3_transaction")
public class Transaction {
#Id
#GeneratedValue(generator = "assigned-by-code")
#GenericGenerator(name = "assigned-by-code", strategy = "assigned")
#Column(name = "transactionid", unique = true, nullable = false)
private Long transactionid;
#Column(name = "transactiontype", nullable = false, length = 10)
private String transactiontype;
#Column(name = "transactionstatus", nullable = false, length = 10)
private String transactionstatus;
#oneToOne
private TransactionRecord record;
}
I want to persist both objects at a same time. when I persist a TRANSACTION, TRANSACTION_RECORD should be persist in it's table. Is there any way to do this ?
You can change the table structure if you want. Only thing i need it TWO tables.
Works with
#OneToOne(cascade=CascadeType.ALL)
#MapsId
private TransactionRecord record;
TransactionRecord must have an #Id of the same type as Transaction with no value generation.
Tried with Hibernate as JPA 2.0-provider.
There are a few options to map this, but it looks like you are handling it with two separate entities. As both entities share the same primary key value, your reference mapping will need to change based on which entity you wish to have controlling the pk value generation - as it stands, the e3_transaction.transactionid field is being set by two separate mappings; the transactionid long and the TransactionRecord record reference.
If you wish to use the #MapsId as is suggested in the other answer, you will need to move your #GeneratedValue code to the TransactionRecord entity, as the JPA provider will use the value in the referenced TransactionRecord to set the transactionid attribute and the database field. This is a simple elegant solution, but you can also remove the Long transactionid attribute from Transaction and just mark the record reference with #Id (instead of #MapsId). The long transactionId value within TransactionRecord would still be used as Transaction's id for EntityManager getReference and find calls.
A different option that allows keeping the #GeneratedValue on the transactionid within Transaction is to define the #JoinColumn annotation on the record reference and specify that the field is insertable=false, updatable=false. You then need to modify the TransactionRecord so that it has a back relationship to the Transaction so that it can pull the transectionid value from the Transaction instance to use as its id. This can be accomplished by simply marking the relationship with #ID though.