How to conditionally delete in DynamoDB using AppSync and Amplify - aws-appsync

I'm a newbie to DynamoDB and AppSync. I have a Tasks table and a TaskType table.
type TaskType
#model
#key(name: "tasktypesOrgIndex", fields: ["orgID"], queryField: "tasktypesByOrganization")
{
id: ID!
orgID: ID!
name: String!
description: String!
type: TaskKeyword
task:[Task] #connection
}
type Task
#model
{
id: ID!
orgID: ID!
name: String!
description: String!
type: TaskKeyword
}
enum TaskKeyword {
TASK
SUBTASK
}
When someone tries to delete an entry from TaskType that has associated Tasks, I need to stop him from doing so. How can I do this?

Related

Prisma constraint not available

I`m using Prisma with NestJS and PostgreSQL
In my schema.prisma i have this
model User {
userId Int #id #default(autoincrement())
firstName String? #db.VarChar(25)
lastName String? #db.VarChar(25)
login String #unique #db.VarChar(60)
email String #unique
password String
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
role Role? #default(ADMIN)
createdUsers User[] #relation("createdBy")
createdBy User? #relation("createdBy", fields: [creatorId], references: [userId])
creatorId Int?
}
enum Role {
ADMIN
MANAGER
WAREHOUSE
USER
}
So when a make create request like this
{
login: "A",
email: "A",
password: "A"
}
it saves in DB - that`s ok. By after the same request i get this error "Unique constraint failed on the (not available)". So shouldn't there be a not unique column name instead of (not available) or that is ok case? Where am i wrong?
I was trying drop table Users and make different unique combs, don`t know what else i can do...
UPD:
async create(createUserDto: CreateUserDto) {
return this.prisma.user.create({
data: {
...createUserDto
}
})
}
export class CreateUserDto {
#IsNotEmpty()
login: string;
#IsNotEmpty()
#IsEmail()
email: string;
#IsNotEmpty()
#MinLength(6)
password: string;
}
UPD 2.0
Finally, moved to TypeORM, it is bug like #num8er mentioned
https://github.com/prisma/prisma/issues/10829
Ty for all the replies

Nested writes in Prisma orm

My schema looks like this:
model Transaction {
id BigInt #id #default(autoincrement())
description String? #db.VarChar(256)
category Category? #relation(fields: [categoryId], references: [id])
createdById Int #map("fk_created_by")
createdBy UserAccount #relation("category_fk_created_byTouser_account", fields: [createdById], references: [id]
}
model Category {
id Int #id #default(autoincrement())
name String #db.VarChar(40)
categoryFilters CategoryFilter[]
}
model CategoryFilter {
id BigInt #id #default(autoincrement())
words String #db.VarChar(255)
categoryId Int? #map("fk_category_id")
}
My question is why this works:
await prisma.workspaceTransaction.create({
data: {
description: 'any',
createdBy: {
connect: {
id: 1
}
},
category: {
create: {
name: 'Este é um teste',
createdById: 1,
categoryFilters: {
createMany: {
data: [
{
words: 'Novo teste'
}
]
}
}
}
}
}
})
And this not?
await prisma.workspaceTransaction.create({
data: {
description: 'any',
createdById: 1,
category: {
create: {
name: 'Este é um teste',
createdById: 1,
categoryFilters: {
createMany: {
data: [
{
words: 'Novo teste'
}
]
}
}
}
}
}
})
The only difference between those two examples is in createdBy command. And i can create Transaction without nested objects with createdById argument. Any one know why this works this way? Or there is something i am missing?
The error given is:
Unknown arg createdById in data.createdById for type TransactionCreateInput
In the second example, you are directly writing a foreign key (createdById) which is considered unsafe, what if there is no UserAccount corresponding to createdById.
While using connect in the first example it would throw an error if Prisma cannot find an UserAccount corresponding to id 1.
First example is the preferred approach.

Typeorm, MongoDB and TypeGraphQL - Populate - Lookup

I am working with Typeorm and MongoDB. I have a UserAlert entity that saves the _id of another User entity as a field. My question is how you can get the information of the entity that that _id refers to. It would be something similar to populate in mongoose.
Example:
User:
#Entity({ name: 'Users' })
export default class User extends BaseEntity {
#ObjectIdColumn()
_id!: ObjectID;
#Column('string')
firstName!: string;
#Column('string')
lastName!: string;
#Column('string')
phoneNumber!: string;
}
User Alert:
#Entity({ name: 'UserAlerts' })
export default class UserAlert extends BaseEntity {
#ObjectIdColumn()
_id!: ObjectID;
//REFERENCE
#ObjectIdColumn()
userId!: ObjectID;
#Column('date')
date!: Date;
}
Result: User Alert
{
"_id":"asdbfsdf32112312dasdas",
"date":"15/09/2021",
"User":{
"_id":"asdas6d5412634123654",
"firstName":"Jorge",
"lastName":"Mamani",
"phoneNumber":"465465"
}
}
How would I have to present the data in Type GraphQL?

Creating a unique ID for an object in YapDatabase

Suppose I have a collection of Users in a YapDatabase. How do I assign each user a unique identifier upon creation?
struct User: Codable{
public var name: String
private var id: ???
}
I've seen UUID in the Apple developer documentation. Having done some reasearch, it seems more for use in distributed systems, athough I suppose it could work. Are there other alternatives? Is there a "standard" method for giving objects a unique id in a relational database?
Possible variants:
1) String (unique everywhere & forever)
struct User: Codable{
public var name: String
private var id: String // = UUID().uuidString
}
2) Int (unique inside your users context, enough in majority of cases)
struct User: Codable{
public var name: String
private var id: Int = 0 // = lastUser.id + 1, where 0 is a new non stored
}

Best approach to make class design if we have two class as bellow :

Best approach to make class design if we have two class as below:
class Teacher {
var name
var age
var TechId
}
class Student {
var name
var age
var StdID
}
I try it using that :
class Person {
var name
var age
}
class Student : Person {
var StdID
}
class Teacher : Person {
var TechID
}
But now problem is that student become teacher and vice versa.
Can you any one provided best solutions for that using Swift?
You said:
But now problem is that student become teacher and vice versa.
If you can change back and forth like this, I'd first suggest a concrete and distinct object to capture what precisely is transitioning from one to the other:
class Person {
var name: String
var age: Int
}
Note, in your example, you are considering this Person to be what other languages consider to be an abstract/virtual class. But I'm suggesting that you want to make this a concrete object (the actual person) that you instantiate.
The question then becomes how you represent "student" and "teacher". One simple pattern is to consider it a question of membership in some relevant collection:
typealias StudentID = String
var students: [StudentID: Person]
typealias TeacherID = String
var teachers: [TeacherID: Person]
In that case, transitioning from a student to a teacher (or vice versa) is merely a question of adding/removing from the appropriate dictionaries.
The above is a bit constrained, though. For example, what if you wanted to keep track of more student-specific properties (e.g. enrollment date, etc.) or teacher-specific properties (e.g. hire date, social security number, annual salary, etc.). This suggests you might want specific types for these student and teacher types:
class Student {
let studentID: String
let person: Person
}
class Teacher {
let teacherID: String
let person: Person
}
And then your students and teachers collections become simple arrays:
var students: [Student]
var teachers: [Teacher]
But by making the Person a property (rather than a base class), if you know which person is associated with a particular "student id", you can now associate that person with a particular "teacher id", too. But the idea is the same, it's merely a question of membership in the appropriate collection/type, not an issue of trying to change the inherent type of the person.
The alternative is a protocol oriented pattern:
protocol Person {
var name: String { get }
var age: Int { get }
}
struct Student: Person {
let studentID: String
var name: String
var age: Int
init(name: String, age: Int) {
studentID = UUID().uuidString
self.name = name
self.age = age
}
init(person: Person) {
self.init(name: person.name, age: person.age)
}
}
struct Teacher: Person {
let teacherID: String
var name: String
var age: Int
init(name: String, age: Int) {
teacherID = UUID().uuidString
self.name = name
self.age = age
}
init(person: Person) {
self.init(name: person.name, age: person.age)
}
}
This captures your notion that Person is an abstract type that simply conforms to having certain properties. It avoids any ambiguity that Person is not a type, itself, but merely a protocol to which types have to conform. You can only instantiate concrete Student and Teacher objects.
But then, if you want to create a Teacher from a Student, you can do:
let fred = Student(name: "Fred", age: 22)
let teacher = Teacher(person: fred)
Note, though, that this doesn’t “change” fred into a Teacher, but rather creates a new Teacher whose Person properties are copies of those of fred.
For Swift, I would recommend something like this:
protocol Person {
var name: String { get }
var age: Int { get }
}
struct Teacher: Person {
let id: Int
let name: String
let age: Int
}
struct Student: Person {
let id: Int
let name: String
let age: Int
}
Use a Protocol to define the person. And use a Struct for Teacher and Student because once created you would not change their details as a Struct is immutable. Both Teacher and Student conform to Person protocol.
To test if a person is a Teacher or Student, you could do this:
func test(person: Person) {
switch person {
case is Teacher:
print("teacher")
case is Student:
print("student")
default:
preconditionFailure("Unknown person type")
}
}