How do insert data into this schema? - node.js

Below is my prisma schema
model Allegations {
allegation_id String #id #db.VarChar(200)
faculty String? #db.VarChar(200)
department String? #db.VarChar(200)
course String? #db.VarChar(200)
instructor String? #db.VarChar(200)
instructorEmail String? #db.VarChar(200)
instructorPh String? #db.VarChar(200)
details String? #db.VarChar(200)
allegationDate DateTime? #db.DateTime(0)
violationDate DateTime? #db.DateTime(0)
Students Students[]
}
model Students {
id String #id #db.VarChar(200)
student_name String? #db.VarChar(200)
banner String? #db.VarChar(200)
allegation_id String? #db.VarChar(200)
Allegations Allegations? #relation(fields: [allegation_id], references: [allegation_id], onDelete: Restrict, onUpdate: Restrict, map: "Students_ibfk_1")
##index([allegation_id], map: "allegation_id")
}
So far I got his but getting errors. I also tried inserting seperately into allegations and students, but the insert in students doesn't go through.
prisma.allegations.create({
data: {
allegation_id:key,
faculty: Faculty,
department: Department,
course: Course,
instructor: Instructor,
instructorPh: PhoneNumber,
instructorEmail: InstructorEmail,
details: Details,
allegationDate: date,
violationDate: OffenceDate,
Students:{
create:{
student_name: 'kn',
banner: '555555'
},
}
}
});

Modifying your code snippet slightly, I was able to correctly insert a record into the database. Also, you have to specify the student ID because you do not have the #default attribute on the Student schema. Find the modified code below
const allegation = await prisma.allegations.create({
data: {
allegation_id:"1",
faculty: "Science",
department: "Biochemistry",
course: "BCH101",
instructor: "John Doe",
instructorPh: "+231345678",
instructorEmail: "johndoe#test.com",
details: "some details",
allegationDate: new Date('2022','07', '31'),
violationDate: new Date('2022','08', '01'),
Students:{
create:{
id: 'std1',
student_name: 'Test Student',
banner: '555555'
},
}
}
})

Related

Prisma ORM | MongoDB - how to group documents by mutiple attributes and list the rest of them

I'm developing a quite simple backend application with Express, using Prisma ORM to connect to a MongoDB database.
The events collection is filled with documents such as:
{
"_id": string,
"class_code": string
"class_type": string,
"created_by": string,
"end_period": date,
"end_time": time,
"has_to_be_allocated": boolean
"pendings": int,
"preferences": {
"accessibility": boolean
"air_conditioning": boolean,
"building": string,
"projector": boolean
},
"start_period": date,
"start_time": time,
"subject_code": string,
"subject_name": stirng,
"subscribers": int,
"updated_at": timestamp,
"vacancies": int,
"week_day": string,
"building": string,
"classroom": string
}
My prisma schema is:
type Preferences {
accessibility Boolean?
air_conditioning Boolean?
building String?
projector Boolean?
}
model events {
id String #id #default(auto()) #map("_id") #db.ObjectId
class_code String
subject_code String
subject_name String
week_day String
class_type String
start_period String
end_period String
start_time String
end_time String
has_to_be_allocated Boolean
pendings Int
subscribers Int
vacancies Int
created_by String
updated_at String
preferences Preferences?
professor String?
classroom String?
building String?
}
Multiple different documents could have the same class_code and subject_code, but different week_day, start_time, end_time, building and classroom attributes.
My intention is to perform a single query so that I end up with a list of objects like such:
{
"subject_name":"Subject name",
"subject_code":"Subject code",
"class_code":"1",
"professor":"professor name",
"start_period":"2023-03-13",
"end_period":"2023-07-15",
"schedule":[
{
"id":"1",
"week_day":"monday",
"start_time":"09:20",
"end_time":"11:00",
"building":"building 1",
"classroom":"C2-03"
},
{
"id":"2",
"week_day":"thursday",
"start_time":"07:30",
"end_time":"09:10",
"building":"building 2",
"classroom":"C2-08"
},
{
"id":"3",
"week_day":"friday",
"start_time":"07:30",
"end_time":"09:10",
"building":"building 3",
"classroom":"C2-04"
}
]
}
That is, I want to group the documents by subject_code and class_code simultaneously, while listing the rest of the differing information between the documents as schedule.
I could always fetch all documents and algorithmically create the object I need, but that would be rather inefficient (and lame).
Any thoughts on how to perform such task? I've been playing around with Prisma's groupBy API but without any success - needless to say, I'm new to it.
So far all I've got is a route which filters the database by subject_code and class_code, and that works fine:
const classInfo = await prisma.events.findMany({
where: {
subject_code:
equals: subjectCode as string,
},
class_code: {
endsWith: fullClassCode,
},
},
});
I then map the retrieved object to the format I need:
const classDetail = {
subjectName: classInfo?.[0]?.subject_name,
subjectCode: classInfo?.[0]?.subject_code,
classCode: getAbbreviatedClassCode(classInfo?.[0]?.class_code),
professor: classInfo?.[0]?.professor,
startPeriod: classInfo?.[0]?.start_period,
endPeriod: classInfo?.[0]?.end_period,
schedule: classInfo.map((event: Event) => ({
id: event?.id,
weekDay: mapWeekDays(event?.week_day),
startTime: event?.start_time,
endTime: event?.end_time,
building: event?.building,
classroom: event?.classroom,
})),
};
What I need is to list all combinations of subject_code and class_code while obtaining objects like the one I mentioned above.
Ok I am no expert in prisma or mongodb but you can try the following (If this basic query works, just modify it to include the additional fields):
const agg = [
{
'$group': {
'_id': {
'class_code': '$class_code',
'subject_code': '$subject_code'
},
'schedule': {
'$push': {
'week_day': '$week_day',
'start_time': '$start_time'
}
}
}
}
]
const result = await prisma.events.aggregateRaw({
pipeline: agg,
});
References:
https://www.mongodb.com/docs/manual/reference/operator/update/push/
https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/#pivot-data
What does your events prisma schema look like? (IE, how is it defined in the schema.prisma file?
Also, is the schedule a separate collection or are these entries simply embedded documents?

PRISMA: How can i select only first string from string array

I'm looking for solution to taking exact element of String Array in Prisma ORM, in my situation, I want to take only first element of paragraphs array to render short article description on the front.
Thats my article model
model articles {
id BigInt #id #default(autoincrement())
articleId Int #unique
scrapedAt DateTime #default(now())
timeString String
time BigInt
title String
url String
img String
paragraphs String[]
}
Assuming we create articles like the code below
const result = await prisma.articles.create({
data:{
articleId: 1,
timeString: "25082022",
time: 25082022,
title: "First Article title",
url: "First Url",
img: "Image URL",
paragraphs: ["First Paragraph for article", "second paragraph"]
}
})
Then we can query for the paragraphs and pick the first one from the result set
const result = await prisma.articles.findFirst({
where:{
id: 1n
},
select:{
paragraphs: true
}
})
console.log(result.paragraphs[0])
The query returns the result in this form
{ paragraphs: [ 'First Paragrah for article', 'second paragraph' ] }
Then the result of logging result.paragraphs[0] is
Output
First Paragraph for article

Prisma Implicit M2N relationship doesn't apply pagination on nested object

have a model with stores and articles.
stores have many articles and articles many stores
As this is an implicit M2N, Prisma has generated automatically the Join table _articlesTohypermarches_stores
The max number of articles per store is 10K, but I want for example only the 10 first and not the whole 10K
I tried to apply pagination when querying the stores but the query sent to the _articlesTohypermarches_stores table has no LIMIT 10 thus resulting in fetching the 10K articles...
here are the query I'm testing, the model and the the queries sent to POSTGRES by Prisma, as well as the PRISMA Logs that showing the pb.
const test = await prisma.hypermarches_stores.findMany({
where: {
id: {
equals: 209,
},
},
select: {
stoDisplayDesc: true,
articles: {
take: 10, // <--- this is not taking into account
skip: 1,
select: {
title: true,
},
},
},
take: 2,
});
model articles {
id Int #id(map: "PK_0a6e2c450d83e0b6052c2793334") #default(autoincrement())
title String? #default("") #db.VarChar(3000)
prioriteId Int?
isAlerte Boolean? #default(false)
categorieId Int?
publicationStartDate DateTime? #default(dbgenerated("'2021-12-29 17:02:14.651'::timestamp without time zone")) #db.Timestamp(6)
publicationEndDate DateTime? #default(dbgenerated("'2021-12-29 17:02:14.651'::timestamp without time zone")) #db.Timestamp(6)
hasAction Boolean? #default(false)
briefDescription String? #default("") #db.VarChar(3000)
content String? #default("")
contact1 String? #default("") #db.VarChar(300)
contact2 String? #default("") #db.VarChar(300)
author String? #default("") #db.VarChar(300)
recordCreationDate DateTime #default(now()) #db.Timestamp(6)
recordUpdateDate DateTime #default(now()) #db.Timestamp(6)
ref_categories ref_categories? #relation(fields: [categorieId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "FK_278d87b271a80d56e5d6cc0f888")
ref_priorites ref_priorites? #relation(fields: [prioriteId], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "FK_a55acd217d26e0d60f57b5f38f7")
articles_documents articles_documents[]
fonctions ref_fonctions[]
magasins hypermarches_stores[]
metiers ref_metiers[]
perimetres ref_perimetres[]
poles ref_poles[]
services ref_services[]
articles_statuts_contribution articles_statuts_contribution[]
##index([id], map: "IDX_0a6e2c450d83e0b6052c279333")
}
model hypermarches_stores {
id Int #id(map: "PK_7b1178bff8dc98cbd6d68fc2dd0") #default(autoincrement())
stoEan String #unique(map: "UQ_7fddfa16362979011e27b4d0b21") #db.VarChar(300)
articles articles[]
##index([id], map: "IDX_7b1178bff8dc98cbd6d68fc2dd")
}

Prisma and node.js complex module issues

I'm going to try my best to reproduce the issues in this case. I'll probably delete it if I can't get the point across well enough. My development environment includes dockerand node.js
I have 7 models within my prisma schema:
User
AuditLog
Finance
VaultTransaction
Empire
WarLogEntry
Structure
The prisma schema is laid out as such
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String #id #default(uuid())
username String
mail String
audit AuditLog[]
empire Empire?
}
model AuditLog {
id String #id #default(uuid())
userId String #map("user_id")
user User #relation(fields: [userId], references: [id])
time DateTime
ip String
client String
i18nKey String #map("i18n_key")
}
model Finance {
id String #id #default(uuid())
gold Float #default(0)
vaultGold Float #default(0)
transactions VaultTransaction[]
empireId String #map("empire_id")
empire Empire #relation(fields: [empireId], references: [id])
}
model VaultTransaction {
id String #id #default(uuid())
financeId String #map("finance_id")
finance Finance #relation(fields: [financeId], references: [id])
i18nKey String #map("i18n_key")
amount Float
}
model Empire {
id String #id #default(uuid())
userId String #map("user_id")
user User #relation(fields: [userId], references: [id])
bannerId Int #default(0) #map("banner_id")
description String?
armory Json
population Json
level Int #default(0)
experience Int #default(0)
attributes Json
turnsAvailable Int #map("turns_available")
race String
class String
finance Finance?
attacks WarLogEntry[] #relation("empire_attacks")
defenses WarLogEntry[] #relation("empire_defenses")
structures Structure[]
}
model WarLogEntry {
id String #id #default(uuid())
battleType String #map("battle_type")
attackerID String #map("attacker_id")
attacker Empire #relation("empire_attacks", fields: [attackerID], references: [id])
defenderID String #map("defender_id")
defender Empire #relation("empire_defenses", fields: [defenderID], references: [id])
turns Int
details Json
}
model Structure {
id String #id #default(uuid())
empireId String #map("empire_id")
empire Empire #relation(fields: [empireId], references: [id])
i18nKey String #map("i18n_key")
category String
attributes Json
}
I have type files, resolver files, service files, and module files for each model, but prisma seems to be having some strange errors. I believe they are circular dependency errors, but I fixed the type files to make each complex module #Field optional so that should've fixed it.
My current errors node.js are as such (they change slightly depending on how i edit the files) It appears it is a prisma issue.
[10:14:54 AM] Starting compilation in watch mode...
src/model/empire/empire.service.ts:8:5 - error TS2322: Type '(Empire & { finance: Finance; attacks: WarLogEntry[]; defenses: WarLogEntry[]; structures: Structure[]; })[]' is not assignable to type 'Empire[]'.
Type 'Empire & { finance: Finance; attacks: WarLogEntry[]; defenses: WarLogEntry[]; structures: Structure[]; }' is not assignable to type 'Empire'.
The types of 'finance.gold' are incompatible between these types.
Type 'Decimal' is not assignable to type 'number'.
8 return prisma.empire.findMany({
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 include: {
~~~~~~~~~~~~~~~~
...
14 },
~~~~~~~~
15 });
~~~~~~~
src/model/finance/finance.service.ts:8:5 - error TS2322: Type '(Finance & { transactions: VaultTransaction[]; })[]' is not assignable to type 'Finance[]'.
Type 'Finance & { transactions: VaultTransaction[]; }' is not assignable to type 'Finance'.
Types of property 'gold' are incompatible.
Type 'Decimal' is not assignable to type 'number'.
8 return prisma.finance.findMany({
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 include: {
~~~~~~~~~~~~~~~~
...
11 },
~~~~~~~~
12 });
~~~~~~~
src/model/vault-transaction/vault-transaction.service.ts:8:5 - error TS2322: Type 'import("/home/paul/dukesthrone/DukesThrone/dt-backend/node_modules/.pnpm/#prisma+client#2.28.0_prisma#2.28.0/node_modules/.prisma/client/index").VaultTransaction[]' is not assignable to type 'import("/home/paul/dukesthrone/DukesThrone/dt-backend/src/model/types/vault-transaction.type").VaultTransaction[]'.
Type 'import("/home/paul/dukesthrone/DukesThrone/dt-backend/node_modules/.pnpm/#prisma+client#2.28.0_prisma#2.28.0/node_modules/.prisma/client/index").VaultTransaction' is not assignable to type 'import("/home/paul/dukesthrone/DukesThrone/dt-backend/src/model/types/vault-transaction.type").VaultTransaction'.
Types of property 'amount' are incompatible.
Type 'Decimal' is not assignable to type 'number'.
8 return prisma.vaultTransaction.findMany();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[10:14:56 AM] Found 3 errors. Watching for file changes.
Here is the finance.service.ts file for model Finance. The return type includes transactions which is of type model VaultTransactions
#Injectable()
export class FinanceService {
async getFinances(): Promise<Finance[]> {
return prisma.finance.findMany({
include: {
transactions: true,
},
});
}
}
Update: im not sure if this is relevant, but i think it may be.
It's an issue tracker on github for circular dependcies in node.js.
https://github.com/MichalLytek/type-graphql/pull/237
Your return type is incorrect as it's not just returning Finance data but also transactions inside Finance.
The type should be:
import { Prisma } from '#prisma/client'
type GetFinances = Prisma.FinanceGetPayload<{
include: { transactions: true }
}>
#Injectable()
export class FinanceService {
async getFinances(): Promise<GetFinances[]> {
return prisma.finance.findMany({
include: {
transactions: true,
},
});
}
}

How do I limit the properties of a query based of a common subproperty?

Given the schema:
{
_id: ObjectID,
city:
{ units:
{ abc: {},
def: { tuid : String },
...
xxx: { tuid : String }
}
}
I would like to return, for a particular _id, all the properties of units who's subproperty tuid is, for example, 123.
I have searched for information about this but array operations keep popping up instead of what I need.
Thank you.

Resources