The Mongo connector currently does not support Cascading Deletes - mongodb

I'm working with Prisma and I want to support CASCADE delete but although I have done everything mentioned in the docs I'm still not getting it to work
this is the error I'm getting when I try to Prisma deploy
Errors:
Restaurant
✖ The Mongo connector currently does not support Cascading Deletes, but the field `foods` defines cascade behavior. Please remove the onDelete argument.}
Here is the code
type Restaurant {
id: ID! #id
name: String!
foods: [Food!]! #relation(onDelete: CASCADE, name: "FoodToRestaurant", link: INLINE)
}
type Food {
id: ID! #id
name: String!
desc: String
price: Float!
category: Category!
restaurant: Restaurant! #relation(name: "FoodToRestaurant", onDelete: SET_NULL)
}
I expect when the restaurant gets deleted all its foods should also be deleted
I have CASCADE deleted with Prisma PostgreSQL but now I want to use MongoDB for this app

As it's not possible, you should manage it manually.
Means you should delete all of related entities recursively.
For example if it's your db schema:
Question -> Comment -> Rate
If you want to delete a question, you should delete all of comments related to that question, and if you want to delete a comment, you should delete all of rates assigned to that comment. So you need some recursive functions for deleting these entities.
function deleteQuestion(questionId) {
for each comment related to questionID
deleteComment(commentId)
delete(questionId)
}
function deleteComment(commentId) {
for each rate related to commentId
deleteRate(rateId)
delete(commentId)
}
function deleteRate(rateId) {
delete(rateId)
}

currently mongodb prisma not support cascading delete. if you have it in your schema please remove it.

Related

Want to change a model ObjectID value

I am creating a Student and Course relationship
A student may have multiple courses. A one to many relationship.
This is made in Express and I'm using MongoDB. I have shorten the models to keep it simple
Student Model
const studentSchema = new mongoose.Schema({
name: {type: String},
courses: [{
type: ObjectId,
ref: 'class'
}]})
Course Model
const classSchema = new mongoose.Schema({
ClassId: {type: String,},
Grade: {type: Number,}, })
Currently, what I have is when I update the grade, it will update the grade values for the course itself and not the course in the user courses.
router.put(....)
const{username, courseId, grade} = req.params
const existingUser = await Student.findOne({username}).populate({
path: 'courses',
select:['ClassId','Grade']
})
const findCourse = existingUser.courses.find(
x => x.ClassId == courseId
)
findCourse.Grade = parseInt(grade)
await findCourse.save()
The problem is this will change the grade for the course itself. Meaning any student that adds this course will have that grade too.
I'll explain what I want to do in Java/OOP terms if that helps.
I want the student object to have it's own course objects. At the moment, it seems like classes are static class objects.
I want to access that specific student courses and change that student grade of that specific course.
Please help, I already spent a couple of hours on this. In SQL, the student would have a reference key and be able to easily change their values, I'm having trouble in MongoDB.
Alright, I finally figured it out. In hindsight, it makes sense. Gave myself a break from coding and came back to see the problem.
Lets pretend we have two students and one course. This courses is seeded with data.
When a student A picks that course, they add it to their course array. When student B wants that course, they also get that exact course. Now they are sharing the course. Basically, they are sharing the same reference.
The solution to this is to still find the course. Now make a new course object, copy every value of the original to the copy. Save the copy to the database and now you add that course to the student. Now we can still register for courses and use the seeded data and students don't share anymore.

Using another table field as owner field for DataStore Authentication

Which Category is your question related to?
DataStore (GraphQL API)
Amplify CLI Version
7.6.23
What AWS Services are you utilizing?
DataStore (GraphQL API)
Provide additional details e.g. code snippets. Be sure to remove any sensitive data.
I am trying to build a service where people can buy subscriptions to certain "Persons" and consume their information. I want to restrict people so that they can only access the data of a certain medium when they are subscribed to it.
Here is the basic structure:
type Post #model {
id: ID!
text: String!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
}
type Person #model {
id: ID!
name: String!
posts: [Post] #hasMany(indexName: "byPerson", fields: ["id"])
}
type Subscription #model {
id: ID!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
userSub: String! // or whatever data we need to reference the user
}
So we have Subscriptions to Persons and Persons can have multiple posts. It is not necessary to fetch a Person if you want to fetch the Posts that a user should be able to see.
What should be possible:
Users should only be able to fetch the posts of the persons that they are subscribed to. There are two ways that I can think of doing but they all require me to change/update data. Since all the data is present, I am not a fan of such solutions.
Solution #1:
Add a group to each user, attach it to the post and add the user to the group as soon as he subscribed
type Post #model #auth(rules: [{ allow: groups, groupsField: "groups" }]) {
id: ID!
text: String!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
groups: String!
}
Not a fan, it requires me to create a group each time a Person is created and I basically have duplicated information here with each post.
Solution #2:
Use an owner field and attach the user as soon as he subscribes
type Post #model #auth(rules: [{ allow: owner, ownerField: "subscribers" }]) {
id: ID!
text: String!
personID: ID! #index(name: "byPerson")
person: Person! #belongsTo(fields: ["personID"])
subscribers: [String]
}
Not a fan as well, I need to edit all the postings as soon as a user subscribes/cancels his subscriptions. The margin of error and amount of calculations here could be huge
I have thought about using a custom resolver (no idea if that works, I don't fully understand it yet) or a custom lambda auth check. The custom lambda auth check causes some issues in the frontend with DataStore. Apparently I need to manually refresh the token for the API or something like that.
What do I want to do?
I would love to use the subscription userSub field as an owner field for the posts. Is that possible (with DataSync) in any way?

TypeORM Postgres - there is no unique constraint matching given keys for referenced table

I am getting the error:
there is no unique constraint matching given keys for referenced table
My models are as follows:
#Entity()
export class User {
#PrimaryGeneratedColumn('uuid')
userId: string
#OneToMany(() => Position, position => position.user)
positions: Position[]
}
#Entity()
export class Position {
#PrimaryGeneratedColumn()
positionId: number
#ManyToOne(() => User, user => user.positions)
user: User
}
It seems like using the UUID strategy might be the error? But I also noted that the generated query defines the userID column with PK contraint:
ALTER TABLE "user" ADD CONSTRAINT "PK_d72ea127f30e21753c9e229891e" PRIMARY KEY ("userId")
Any help is very much appreciated.
In the end I realise there is some polluted migration files inside of /dist that was messing with the database. After deleting /dist and having all files regenerated, the problem was gone.
Polluted /dist is apparently a problem not well looked into and can affect tsnode-dev, typescript, nodemon, and nestjs dev instances that generates /dist on the fly and incrementally.

Implementing 3 way relationship in Prisma

I also asked this question on Prisma forum.
** EDIT **: The forum has since been locked as read-only just 1 day after my question. It's sure getting scary because there is no official announcement of whether they'll stop developing Prisma 1 after implementing promised features or not. Surely they could have said something. And TBH, the unstable Prisma site does add to my shaking confidence in Prisma despite the number of stars in their repo.
I'm new to Prisma. So I have a 3-way relationship between User, Event and Role I would like to define. For each association of a User and an Event, there exists a Role for that association. If I were to design a database table for another ORM, I would have created a event_user table with user_id, event_id and role_id as columns to relate them.
Practically, a row of these 3 columns must be unique. Obviously, it would be good if Prisma can do the safeguarding of these constraints, but the obvious solution I see might not even come to Prisma 1.
My current design consists of the following:
type User {
// ...
eventUsers: [EventUser!]!
}
type Event {
// ...
eventUsers: [EventUser!]!
}
type EventUser {
role: Role!
event: Event!
user: User!
}
This design will make render all xxWhereUniquexx unusable, which is definitely a hassle to maintain relationships. upserts will certainly be unusable for maintaining the relationships.
How would one create a relationship like this in Prisma?
For some context, each user would have a list of global roles as well, so there would already be an association between User and Role. The question concerns the "local roles" for each event.
If each user already have a value for their respective roles, there would be no need for a third table (unless there is more information you'd like to be stored in your modal layer in which case the role type should be in the Role table).
Relationships are set with the #relation directive. You can apply it to either one of two tables in a relation but for clarity I'm apply them to the Event table. The example assumes users can be part of several events.
Tables:
enum ROLE_TYPE {
TYPE_ONE
TYPE_TWO
}
User {
user_id: ID! #id
events: [Event!]!
}
Event {
event_id: ID! #id
users: [User!]! #relation(link: INLINE)
}
Role {
role_id: ID! #id
type: ROLE_TYPE
event: Event! #relation(link: INLINE)
user: User! #relation(link: INLINE)
}
You can read more about relations on the Prisma site

MongoDB Schema Design - New Collection or Reference?

I bumped into a question regarding the schema for MongoDB. With reference to the example on MongoDB Schema Design, regarding the db.students and db.courses.
As I am more used to SQL structured, I am still confused with this reference or embed problem. So, the example is only showing the course within the db.students, is referenced to the db.courses. So if I were to categorize my courses such as humanities, languages, etc, how should I do it?
What would be a better way to do it?
1. create a collection called `db.categories` and reference the db.courses to it?
// db.courses
{ name: Biology, cat: 1 }
{ name: English, cat: 2 }
// db.categories
{ cat: 1, name: Humanities }
{ cat: 2, name: Languages }
2. to just embed within the courses?
// db.courses
{ name: Biology, cat: Humanities }
{ name: English, cat: Languages }
{ name: History, cat: Humanities }
Could anyone please kindly advise, what should I be doing?
Thank you.
Introduction:
In yours case both variants will be good because category just enumeration an you don't need load category in order to display course, you just need create some enumeration and get category name by id.
But in for example if you have table db.users and each user have collection of db.courses you don't need create separate document your just need nested collection courses. And it's really cool because in sql you need create separate table with one to many reference.
The one big benefit of document database is that you can create big documents with nested collections and no need to join tables.
Answer:
So in your case i suggest two ways:
Create enumeration for categories and get category name by id( but not load from mongo).
Just copy category name in course( But first case better because in case if category name was changed your need update each course with new category name).