Prisma returns empty response when fetching data - mysql

I have data in the table but prisma returns empty response.
Database is hosted on Planetscale and it is MySQL.
This is schema of the table:
model BindingTeacherLessons {
bindingId Int
teacherId Int
lessons Int
binding Binding #relation(fields: [bindingId], references: [id], onDelete: Cascade)
teacher Teacher #relation(fields: [teacherId], references: [id], onDelete: Cascade)
##id([bindingId, teacherId])
##index([bindingId])
##index([teacherId])
}
This query returns {} and no errors
const response = prisma.bindingTeacherLessons.findMany({})

It seems that the problem was that I have populated BindingTeacherLessons table with createMany(). Fix was to populate it with create().

Related

How can i fetch data from another table referenced by foreign key?

Heres my tables that a wanna fetch the data, i am using express to make a get request from the next app:
model Provider {
id String #id #default(cuid())
name String
email String
password String
phone String
photo String?
service Service? #relation(fields: [serviceId], references: [id])
serviceId String?
location Location? #relation(fields: [locationId], references: [id])
locationId String?
createdAt DateTime #default(now())
text String
starAverage Float
medals Medals[]
comment Comment[]
}
model Service {
id String #id #default(cuid())
type String
provider Provider[]
}
I wanna fetch the type of the service of the services table of a provider, not the serviceId, and this is my route.
router.get('/list', async (req: Request, res: Response) => {
const allClients = await prisma.client.findMany()
res.json({allClients})
})
this is how i am fetching the data of the rest API using axios
const [providers, setProviders] = useState([] as any[])
useEffect(() => {
axios.get('http://localhost:5140/providers/list')//my list of all providers
.then(res => {
console.log(res)
setProviders(res.data)
}).catch(err => {
console.log(err)
})
}, )
const renderedProviders = Object.values(providers).map(provider => {
return (
<div
className="card"
style={{ width: "18rem"}}
key={provider.id}
>
<img className="card-img-top" src="..."/>
<div className="card-body">
<h3>{provider.name}</h3>
<p>{provider.starAverage} estrekas</p>
<p>{provider.serviceId}</p>
</div>
</div>
);
});
return (
<div className="d-flex flex-row flex-wrap justify-content-between">
{renderedProviders}
</div>
)
for now a only get the serviceId of a provider, not the type of the service
To fetch data from another table referenced by a foreign key in a database, you can use a JOIN clause in your SQL query. A JOIN clause allows you to combine rows from two or more tables based on a related column between the tables.
this how you can use a JOIN clause to fetch data from two tables, users and orders, that are related by a foreign key.
SELECT users.*, orders.*
FROM users
JOIN orders ON orders.user_id = users.id
the JOIN clause combines rows from the users and orders tables based on the user_id column in the orders table and the id column in the users table. The SELECT clause specifies the columns to be retrieved from the users and orders tables.
Edited
how you can reference this in the express route and in the http request from axios ?
you can use the sequelize.query(Sequelize is a promise-based Node.js ORM) method to execute a raw SQL query.
app.get('/users/:id', (req, res) => {
const { id } = req.params;
const query = `
SELECT users.*, orders.*
FROM users
JOIN orders ON orders.user_id = users.id
WHERE users.id = :id
`;
const replacements = { id };
sequelize.query(query).then(([results, metadata]) => {
res.send(results);
});
});
the sequelize.query method is used to execute a raw SQL query that includes a JOIN clause to fetch data from the users and orders tables.

How to create one to many relationship from many to many join table in Prisma

I am creating a workout app and would like to model the relationship between users and workout programs. A user can create a program multiple times.
Here are my Prisma models:
model User {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
email String #unique
firstName String #db.VarChar(50)
lastName String #db.VarChar(50)
password String #db.VarChar(191)
programs ProgramEnrollment[]
}
model ProgramEnrollment {
program Program #relation(fields: [programId], references: [id])
programId Int // relation scalar field (used in the `#relation` attribute above)
user User #relation(fields: [userId], references: [id])
userId Int // relation scalar field (used in the `#relation` attribute
assignedAt DateTime #default(now())
##id([programId, userId])
}
model Program {
id Int #id #default(autoincrement())
name String
users ProgramEnrollment[]
}
The above works nicely, but now what I am trying to do is let the user record their personal program results, so I add the following:
model ProgramEnrollment {
program Program #relation(fields: [programId], references: [id])
programId Int // relation scalar field (used in the `#relation` attribute above)
user User #relation(fields: [userId], references: [id])
userId Int // relation scalar field (used in the `#relation` attribute
assignedAt DateTime #default(now())
userProgram UserProgram[]
##id([programId, userId])
}
model UserProgram {
id Int #id #default(autoincrement())
name String
userProgramEnrollment ProgramEnrollment #relation(fields: [programEnrollmentId], references: [id])
programEnrollmentId Int // relation scalar field (used in the `#relation` attribute above)
}
When I make the above changes I get the following error: Error validating: The argument references must refer only to existing fields in the related model ProgramEnrollment. The following fields do not exist in the related model: id
Why will it not let me create a one to many relationship from a many to many join table?
As docs states composite ID (##id) cannot be defined on a relation field.
You can probably use ##unique to define a compound unique constraint instead, like that: #unique([programId, userId]), and then just use regular autogenerated id for ProgramEnrollment and then you will be able to use it in a relation for UserProgram
I just need to adjust the UserProgram model a bit to account for multi-field id in the ProgramEnrollment model.
model ProgramEnrollment {
program Program #relation(fields: [programId], references: [id])
programId Int // relation scalar field (used in the `#relation` attribute above)
user User #relation(fields: [userId], references: [id])
userId Int // relation scalar field (used in the `#relation` attribute
assignedAt DateTime #default(now())
userProgram UserProgram[]
##id([programId, userId])
}
model UserProgram {
id Int #id #default(autoincrement())
name String
userProgramEnrollment ProgramEnrollment #relation(fields: [programEnrollment_programId, programEnrollment_userId], references: [programId, userId])
programEnrollment_programId Int
programEnrollment_userId Int
}
Since ProgramEnrollment uses two fields for its id, we have to reference both of them in the UserProgram model.

Prisma Many To Many multiple update

I have a problem with the Prisma ORM.
I have a Many To Many relation, this is the structure :
id Int #id #default(autoincrement())
last_name String #db.VarChar(255)
first_name String #db.VarChar(255)
...
report report_author[]
...
}
model report {
id Int #id #default(autoincrement())
type Int
content String #db.LongText
appreciation String? #db.VarChar(255)
meeting_id Int
meeting meeting #relation(fields: [meeting_id], references: [id], onDelete: Cascade, map: "report_ibfk_1")
users report_author[]
##index([meeting_id], map: "report_ibfk_1")
}
model report_author {
id Int #id #default(autoincrement())
report_id Int
author_id Int
user user #relation(fields: [author_id], references: [id], onDelete: Cascade, map: "report_author_ibfk_1")
report report #relation(fields: [report_id], references: [id], onDelete: Cascade, map: "report_author_ibfk_2")
##index([report_id], map: "report_author_ibfk_1")
##index([author_id], map: "report_author_ibfk_2")
}
Well, there is no problem about it ! My goal is to CONNECT an array of USERS who gonna be linked in my request. To be clear, my sended object will be like:
id: 2,
type: 2,
content: '<p>I love it !</p>',
appreciation: 'Favorable',
meeting_id: 13,
report_author: [{report_id:2, author_id:70},{report_id:2, author_id:70}]
But sometimes, in this array:
report_author: [{report_id:2, author_id:70},{report_id:2, author_id:70}] I will have 3,4 maybe 5 object.
My question is :
How can I insert (link) a variable number of user to a REPORT thanks to prisma update, upsert, connect or any query ?
Thank you !

Join 3 tables based on column values - Laravel

LEADS TABLE
id
title
owner_id
from_table
EMPLOYEE TABLE
id
first_name
last_name
role
ADMIN TABLE
id
first_name
last_name
role
$users = Leads::query();
return Datatables::make($users)
->editColumn('owner_id', function ($user) {
if($user->from_table == 'employee'){
$emp = Employee::where('id',$user->owner_id)->first();
return $emp->first_name.' '.$emp->last_name.' ('.$emp->role.')';
}
if($user->from_table == 'admin'){
$admin = Admin::where('id',$user->owner_id)->first();
return $admin->first_name.' '.$admin->last_name.' ('.$admin->role.')';
}
})
the above solutions is working fine but we are unable to search column wise induvidual searching in datatables.
what i want is join query something like:
if(leads.from_table == employee)
// fetch data from EMPLOYEE TABLE i.e. LEADS TABLE + EMPLOYEE TABLE
id
title
owner_id
from_table
first_name
last_name
role
if(leads.from_table == admin)
// fetch data from ADMIN TABLE i.e. LEADS TABLE + ADMIN TABLE
id
title
owner_id
from_table
first_name
last_name
role
I think you should change your database structure to use polymorphic relations, they fully comply with your needs - https://laravel.com/docs/5.8/eloquent-relationships#polymorphic-relationships
from_table column should contain the class name of the parent model.
Add in Leads model
public function fetchOwner()
{
return $this->morphTo();
}
Add In Employee Model
public function employee()
{
return $this->morphOne('App\Employee', 'fetchOwner');
}
Add In Admin Model
public function employee()
{
return $this->morphOne('App\Admin', 'fetchOwner');
}
$users = Leads::with('fetchOwner');
return Datatables::make($users)
->editColumn('owner_id', function ($user) {
return $user->fetchOwner->name;
})
thanks to all who tried to help..
I'm answering my own question as i found the answer after 9 days digging everywhere..
so here is the answer:
you may want to replace owner_code by owner_id in your business table.
so i changed the from_table to owner_type & owner_type now should contain the class name as value ex: changed admin to App\Admin & employee to App\Employee in Database
App\Admin.php
public function employee()
{
return $this->morphOne('App\Leads', 'owner');
}
App\Employee.php
public function employee()
{
return $this->morphOne('App\Leads', 'owner');
}
App\Leads.php
public function owner()
{
return $this->morphTo();
}
Thanks to: laravel morphTo how to use custom columns? (EddyTheDove) for pointing out the exact problem..

Sequelize selecting id instead of foreign key

I have a Book table, a Category table and a join table named BookCategories. Here's an oversimplified structure:
books {
id,
name,
hash // unique
}
categories {
id,
name
}
book_categories {
id,
book_hash,
category_id
}
Because of the way the app works, it was decided to use the book_hash in the join table instead of the book_id.
Here are the Sequelize relations between the 3 tables:
// book
Book.hasMany(models.bookCategories, { foreignKey: 'book_hash' });
// category
Category.hasMany(models.bookCategories, { foreignKey: 'category_id' });
// bookCategories
BookCategories.belongsTo(models.book, { foreignKey: 'collection_hash' });
BookCategories.belongsTo(models.category, { foreignKey: 'category_id' });
I'm using Sequelize with GraphQL, so when creating the books field on the CategoryType, everything works great:
books: {
type: new GraphQLList(BookType),
args: defaultListArgs(),
async resolve(f, args) {
return await f.getBookCategories(args);
// normally doesn't return, uses results to get book hashes and return books
}
}
It runs the following queries:
SELECT `id`, `name` FROM `categories` ASC;
SELECT `id`, `book_hash`, `category_id` FROM `book_categories` AS `bookCategories` WHERE `bookCategories`.`category_id` IN (1, 2, 3, 4, 5);
But when doing it the other way around, requesting the bookCategories through the BookType, it doesn't:
categories: {
type: new GraphQLList(CategoryType),
args: defaultListArgs(),
async resolve(f, args) {
return await f.getBookCategories(args);
// normally doesn't return, uses results to get category ids and return categories
}
}
It runs these queries:
SELECT `id`, `name`, `hash`, FROM `books` AS `book` WHERE `book`.`hash` = 'ft3qvqlj';
SELECT `id`, `book_hash`, `category_id` FROM `book_categories` AS `bookCategories` WHERE `bookCategories`.`book_hash` IN (93586);
As you can see, even though I set the foreign key to the hash on both relations, it still uses the book id to do the query. Does it have to do with the fact that hash is not the primary key on the books table?
Is there a way to fix this or do I have to redo the database structure?