how can I select everything from a table with prisma? (SELECT * FROM application)
const applications = prisma.application.findMany({
// Returns all user fields
include: {
posts: {
select: {
age: true,
about_section: true,
user_id: true
},
},
},
})
console.log(applications.age)
Here is how my schema looks:
model application {
application_id Int #id #default(autoincrement())
age String? #db.VarChar(255)
about_section String? #db.VarChar(255)
user_id Int?
users users? #relation(fields: [user_id], references: [user_id], onDelete: Restrict, onUpdate: Restrict, map: "application_ibfk_1")
##index([user_id], map: "user_id")
}
For rows, findMany() without where will return all rows in table:
Get all Records
The following findMany query returns all User records:
const users = await prisma.user.findMany()
For columns/fields, without specifying include or select, prisma has a default:
By default, when a query returns records (as opposed to a count), the
result includes the default selection set:
All scalar fields defined in the Prisma schema (including enums)
None of the relations
For SELECT * FROM application (does not include users relation):
const applications = await prisma.application.findMany();
To futher include users relation in the model:
const applications = await prisma.application.findMany({
include: {
users: true // will include all fields
}
});
Related
I have two Entities, Organization and Applications. One organization can have many Applications.
const organization = mongoose.Schema(
{
name: {
type: String,
required: [true, 'Organization name is required.']
}, // min 1 max 255
// administrators get it from user table with org and role.
applications: [
// use populate in query
{
type: mongoose.Types.ObjectId,
ref: 'Application'
}
]
I am trying to query Organization with two applications and its returning a blank array
const organizations = await Organization.find({
'applications': {
$all: [
'636bdf70bcd2d24005061023',
'6373ba91f53f95ca187809d6'
]
}
}).populate('applications');
I tried running the same expression in MongoDB compass and it works. What am I doing wrong here ?
Based on your schema model, the applications field is an array of ObjectIDs, not an array of objects where each object would have _id property.
So instead of applications._id, it should be applications:
const organizations = await Organization.find({
applications: {
$all: ['636bdf70bcd2d24005061023', '6373ba91f53f95ca187809d6']
}
})
.populate('applications');
I have 2 tables:
model Collection {
id String #id #default(uuid()) #db.Uuid/
floorPrices CollectionFloorPrice[]
}
model CollectionFloorPrice {
id String #id #default(uuid()) #db.Uuid
collection Collection #relation(fields: [collectionId], references: [id])
collectionId String #db.Uuid
}
How do I query collections that only have rows present in CollectionFloorPrice? In SQL it would be a simple JOIN.
This isn't working:
return await this.prisma.collection.findMany({
where: {
floorPrices: {
exists: true,
},
},
});
Prisma's relation filters for a model named CollectionFloorPrice are:
export type CollectionFloorPriceFilter = {
every?: CollectionFloorPriceWhereInput | null
some?: CollectionFloorPriceWhereInput | null
none?: CollectionFloorPriceWhereInput | null
}
To get only Collections that have at least one CollectionFloorPrice, you should use some (instead of exists) and specify a condition that always return true for any related record that exists.
And if you want to your query includes related CollectionFloorPrices you must specify it in include property.
return await this.prisma.collection.findMany({
where: {
floorPrices: {
some: {
id: { not: "" } // It always should be true.
},
},
},
// if you want to include related floor prices in returned object:
include: {
floorPrices: true,
},
});
prisma.collection.findMany({
where: { floorPrices: { some: {} } }
})
I am new to prisma-client and I want to return the latest value register by each user of a given company.
This is my schema.prisma:
model Locations {
id Int #id #default(autoincrement())
user String
company String
latitude String
longitude String
timestamp String
}
This is what I have tried so far:
const lastLocations = await db.locations.findMany({
where: {
company,
},
orderBy: {
id: 'desc',
},
take: 1,
});
But I need to get 1 value for each user, I solved this previously in sql with:
WITH ranked_messages AS ( SELECT m.*, ROW_NUMBER() OVER (PARTITION BY userID ORDER BY timestamp DESC) AS rn FROM locations AS m ) SELECT * FROM ranked_messages WHERE rn = 1 AND companyID = "${companyID}";`;
But I have no idea how to do proceed in prisma. Is there an "each" method?
I appreciate any help. Thank you.
I solved using distinct option:
const lastLocations = await db.locations.findMany({
where: {
company,
},
distinct: ['user'],
orderBy: {
id: 'desc',
},
});
Thanks.
I have a User entity which has a OneToOne relation to a Profile entity and the Profile entity has a ManyToMany relation to a Category entity.
// user.entity.ts
#Entity()
export class User {
#PrimaryGeneratedColumn('uuid')
id: string;
#OneToOne(() => Profile, {
cascade: true,
nullable: true,
})
#JoinColumn() // user owns the relationship (User table contains profileId). Use it only on one side of the relationship
profile: Profile;
}
// profile.entity.ts
#Entity()
export class Profile {
#PrimaryGeneratedColumn('uuid')
id: number;
#OneToOne(() => User, (user: User) => user.profile)
user: User;
#ManyToMany(() => Category, (category: Category) => category, {
cascade: true,
nullable: true,
})
#JoinTable()
categories: Category[];
}
// category.entity.ts
#Entity()
export class Category {
#PrimaryGeneratedColumn('uuid')
id: number;
#Column()
name: string;
#ManyToMany(() => Profile, (profile: Profile) => profile.categories, {
nullable: true,
})
profiles: Profile[];
}
My goal is to get all user entities where category names of the profile are all present in a string array as input e.g. const categories = ['category1', 'category2']. So far using IN with a query builder brings me close to my goal.
This is the query with IN:
const categories = ['category1', 'category2']
const users = await this.usersRepository
.createQueryBuilder('user')
.innerJoinAndSelect('user.profile', 'profile')
.innerJoinAndSelect('profile.categories', 'categories')
.where('categories.name IN (:...categories)', {
categories,
})
.getMany();
I want only users where category1 AND category2 are present as names of many to many relations of the profile. With the query above I receive also users where only one of these values are present as names. Is this even possible with my current structure?
This comes close to mine, but there the OP has unrelated entities.
This comes also close, but there it's just a string array column for the filtering.
Also I would like to keep my current structure, because may want to add some other columns to the category entity like an order for example.
Update:
I decided to use a string array instead of a many to many relation since it satisfies my own requirements.
// profile.entity.ts
#Column('text', {
nullable: true,
array: true,
})
categories?: string[];
The updated query:
const categories = ['category1', 'category2']
const users = await this.usersRepository
.createQueryBuilder('user')
.innerJoinAndSelect('user.profile', 'profile')
.where('profile.categories::text[] #> (:categories)::text[]', {
categories,
})
.getMany();
If you're using PostgreSQL, you could use the #> contains array operator.
const categories = ['category1', 'category2']
// untested code
const users = await this.usersRepository
.createQueryBuilder('user')
.innerJoinAndSelect('user.profile', 'profile')
.innerJoin('profile.categories', 'categories')
.groupBy('user.id')
.addGroupBy('profile.id');
.having('array_agg(categories.name::text) #> ARRAY[:...categories]', {
categories,
})
.getMany();
Instead of selecting the categories, it just aggregates the joined categories into an array and checks whether it's a superset of the given array or not. I wasn't able to test this with TypeORM, so I'm just hoping it can deal with the array-building syntax as I couldn't find it anywhere in the documentation. I hope you find this solution helpful.
Edit: Added missing groupBy and missing cast, as mentioned in the comments.
I'm trying to insert multiple JSON data into a table called integration_data using the TypeORM. I'm using NodeJS for my app. But somehow, I'm not able to form the query using TypeORM to perform bulk UpSert of my JSON data in Postgres SQL.
Following is my logic:-
let dbConn = await database.getConnection(connectionOptions);
await dbConn.createQueryBuilder()
.insert()
.into(IntegrationData)
.values(rawdata)
.onConflict(`("id") DO UPDATE SET "empData" = excluded."empData"`)
.execute();
Here, I'm passing rawData which is an array of JSON objects.
Entity:-
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
#Entity({ name: 'integration_data' })
export class IntegrationData {
#PrimaryGeneratedColumn()
id: number;
#Column({ type: 'bigint', nullable: false, name: "emp_id" })
empId: number;
#Column({ type: 'text', nullable: false, name: "integration_name" })
integrationName: string;
#Column({ type: 'json', nullable: false, name: "emp_data" })
empData: object
}
Here emp_data column in the integration_data table is of JSON. Following is my table on Postgres:-
May I know how can I perform an upsert operation i.e. insert if not exists else update the record in Postgres database based on emp_id which is going to be unique.
Cheers
You can use TypeORMs Repository.save() method to do upserts if the column is set as a primary key. You can simply pass an array of the objects into the method.
From the documentation:
/**
* Saves all given entities in the database.
* If entities do not exist in the database then inserts, otherwise updates.
*/