Replies: 37 comments 68 replies
-
Great news! was looking forward to the nest filter for a long time. There is one issue I faced using the current query and it's related to this issue#1378 hoping to see it fixed! |
Beta Was this translation helpful? Give feedback.
-
Looking great! One comment: db.query.pets.findMany({
where: { ownerId: 1, name: "pikachu" }
});
db.query.pets.findMany({
where: { NOT: { userId: 1 } }
})
db.query.pets.findMany({
where: { OR: [{ ownerId: 1 }, { name: "pickachu" }] }
}); These feel too similar, would it be better or worse to use something like a dollar prefix or some other indicator that highlights that "NOT / OR mean something special here and it's not a field" I'm new to Drizzle (loving it so far) so I don't know much about the history or the ongoing conversations - if a dollar prefix or some other "this is a special keyword" indicator was considered already and decided against, fair enough |
Beta Was this translation helpful? Give feedback.
-
I would love to see a better select functionality. I see this: // old
await db.query.test.findMany({
columns: {
field1: true,
field2: true,
field3: true
...
}
})
// maybe future
await db.query.test.findMany({
columns: ["field1", "field2", "field3"] // or something similar
}) Is it just me, or is the composite keys pattern way more complicated than it's available right now? |
Beta Was this translation helpful? Give feedback.
-
I usually avoid leaving unnecessary comments that don't add nothing of value to the discussion. However, just this once.... LETS GOOOO!!! 🎉🎉🎉🚀 |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
This does introduce a vulnerability. Clients may be able to manipulate queries from endpoints. Sequelize uses symbols to protect against this kind of vulnerability: ‘’’ finally, this prevents the case (rare, but possible) that there is a conflict between column names and “special keywords” |
Beta Was this translation helpful? Give feedback.
-
This might not be in the scope of this redesign, but if you're working on the API anyways I'd like to throw in a suggestion. In my database, I use relations with a primary key that I treat as an implementation detail and have a separate public ID that is used externally (very handy for migrating database providers which have different key requirements). I'm not sure it'd work at all with the new syntax, but rather than doing extra database calls to get the public id -> internal, it'd be awesome to be able to do something like this:
It's super useful to be able to use the query for this rather than the more sql-like syntax as the columns & withMap are parsed from a graphql request - this same operation would take at least a few hundred lines of code if I had to write it all out more explicitly. The idea of what I've done above is that tables which are specified in the I've been using a very basic implementation of this in a fork (https://github.com/rmtmckenzie/drizzle-orm/tree/query-joins-v2) but it's definitely not production ready and only implemented for mysql and postgres. It seems like your proposed changes will make this less possible, but if this sparks any ideas I'd appreciate it being considered. (and feel free to lift any code in that branch if it's at all helpful). |
Beta Was this translation helpful? Give feedback.
-
Love the relations changes, the relations API currently is pretty hard to get right when first starting. The new filters API conversion from Prisma projects far easier, my concern with the new filters API is the TypeScript performance on a larger project. Prisma has a codegen step to create the types which would help the approach scale due to less computed types. The current drizzle approach is great from a TypeScript performance point of view, it also it super easy to extract helpers and compose bits of queries together which getting the types right to store parts of queries in variables is pretty hard with the object syntax. It could be good to have an opt out which ensures the types are not included at all for these relations in the case of build performance issues? Unsure if just having those types could impact build performance or you have to use the new syntax to be impacted. At any rate, suggest checking the build perf ( of a large project before/after upgrading to a version with the filters API, then converting a number of queries across then checking build perf again. Once it's released it might be a lot of work to fix large perf issues without breaking changes. |
Beta Was this translation helpful? Give feedback.
-
What does
In the where clause example above, does that mean I can query the above relation like this?: db.query.users.findFirst({
columns: {
// ...
},
with: {
pikachuPets: {
columns: {
// ...
}
}
}
}); |
Beta Was this translation helpful? Give feedback.
-
Great updates. Just a small nit:
Wouldn't it make more sense to have it reverse with a config option? For instance: // Start migrating
export default {
query: 'legacy' // tentatively swap the assignment
} satisfies Config
db.query.pets.findMany // legacy
db._query.pets.findMany // v2 ↓ // Almost finished transition to v2
export default {
query: 'v2' // default
} satisfies Config
db._query.pets.findMany // legacy
db.query.pets.findMany // v2 |
Beta Was this translation helpful? Give feedback.
-
I don't know if this is already included in your changes, but will you include the possibility to have optional |
Beta Was this translation helpful? Give feedback.
-
Will the where clause be available also for the export default relations(schema, (r) => ({
users: {
pikachuPets: r.many({
from: r.pets.ownerId,
to: r.users.id,
where: { // <--- This
petName: "pikachu",
}
}),
},
})); |
Beta Was this translation helpful? Give feedback.
-
I am sure you have considered it seeing you have mentioned a "through" relation, but I want to point out the importance of polymorphic relations when designing the DX. These discussions have some good insights. Exciting stuff! |
Beta Was this translation helpful? Give feedback.
-
One thing I would really hope to see in V2 that has been a pain point for me and has prevented me from using the V1 RQB is the lack of the ability to use where conditions that rely on related tables. For example: db
.select({ id: listings.id })
.from(listings)
.leftJoin(listingVariants, eq(listingVariants.listingId, listings.id))
.where(
exists(db.select().from(listingVariants).where(and(eq(listingVariants.listingId, listings.id), isNotNull(listingVariants.productId))))
) This is annoying since it requires manually joining and using subqueries. This same problem gets even more complicated when my db.query.listings.findMany({ where: {
ALL: { variants: { productId: { NOT: null } } }
}}); |
Beta Was this translation helpful? Give feedback.
-
Sorry if this was discussed above but I skimmed through and didn't find anything. Would this new API allow to infer the type for the relation query? eg:
|
Beta Was this translation helpful? Give feedback.
-
I have no problems with the relational API moving a bit further away from vanilla SQL nomenclature. The relation API is for simple, primitive query so I agree that they should be made as easy as possible. My biggest gripe, however, is currently the type unsafety of the query builder (#2329). I hope that that will also see some love afterwards and be addressed, maybe a Query Builder V2...? :) |
Beta Was this translation helpful? Give feedback.
-
When I work with relations, I often find myself wanting to When I don't have to sort, it's pretty easy: with: {
posts: true
} But as soon as I want to sort them, suddenly I have to import with: {
posts: {
orderBy: [desc(posts.id)]
}
} This works in a simple case, but I have an admin page that handles all tables and their child tables in a common way, and there I want to be able to meta-programming those. (click parent table, drop down relation child tables sorted by timestamp, etc.) If it was just a string and Drizzle handles them with reflection, just like _.orderBy with lodash, it would make Drizzle super powerful for meta programming. (FWIW it's easy to do this with Rails with with: {
posts: {
orderBy: ['posts', 'id', 'desc']
}
} Better yet, we could have default order defined in the relation itself: export default relations(schema, (r) => ({
users: {
pets: r.many({
from: r.pets.ownerId,
to: r.users.id,
orderBy: [desc(r.pets.createdAt)]
}),
},
})) |
Beta Was this translation helpful? Give feedback.
-
Currently the query builder as the name suggests is for fetching the data. Are there any plans to have similar syntax for // current
await db.update(users)
.set({ name: 'Mr. Dan' })
.where(eq(users.name, 'Dan'))
.returning({ updatedId: users.id });
// to something like
await db.update.users({
where: { name: 'Dan' },
data: { name: 'Mr.Dan' },
select: { updatedId: true }
}) or is that not something we could expect going forward, as it's too far away from the sql like roots of drizzle? |
Beta Was this translation helpful? Give feedback.
-
Sorry for intruding here. |
Beta Was this translation helpful? Give feedback.
-
This is probably out of scope, but I think this is a problem many projects have to take care of. If I have a ui that can produce very flexible queries (e.g. a filterable and sortable table), we have to send the query information as a text message (json format) to the api. Then we have to parse the message and convert it into a drizzle query. If drizzle could support a standardized json compatible format that can be easily converted into a drizzle query (maybe with a helper function) this coud save a lot of time. |
Beta Was this translation helpful? Give feedback.
-
Is #1513 still somewhere on some roadmap? |
Beta Was this translation helpful? Give feedback.
-
Hi 👋 Thank you, awesome job! |
Beta Was this translation helpful? Give feedback.
-
Good job on the v2 design, it's looking good ! Am I correct in understanding that we'll have to deal with a gigantic function that can't be split without losing type inference ? If that's the case, migrating to the new schema would feel like a downgrade for users who currently have their tables split in multiple files with their relations neatly defined next to the table definition. Could you please consider this ? Maybe this could potentially be solved with a export const petRelations = tableRelations(schema, (r) => ({
pet: {
ownersM2M: r.many({
from: r.pet.ownerId.through(r.petsToOwners.ownerId),
to: r.user.id.through(r.petsToOwners.petId),
})
}
}));
export const userRelations = tableRelations(schema, (r) => ({
user: {
petsM2M: r.many({
from: r.user.id.through(r.petsToOwners.ownerId),
to: r.pet.ownerId.through(r.petsToOwners.petId),
})
}
}));
const allRelations = relations({ ...userRelations, ...petRelations }) |
Beta Was this translation helpful? Give feedback.
-
Are there any updates on when this might be landing, or any pre-release/work in progress branches to look at? I've been watching this for a while, because this should enable a much better drizzle plugin for pothos. I've been pretty focused on other work lately, but the drizzle plugin is back on the top of my priorities, and I am going to be slowly working on it over the next month or 2. I don't think this is strictly a blocker, but nested filters significantly improve how queries can be constructed. This is probably out of scope, but for nested selections, having the ability to alias selections would be really cool. For example, being able to select drafts and non-drafts from the same post relation db.query.users.findFirst({
columns: {},
with: {
posts: {
where: { draft: false }
},
'drafts:posts': {
where: { draft: true }
}
}
});
// returns something like [{ posts: [...], drafts: [...] }] |
Beta Was this translation helpful? Give feedback.
-
Concerning
This feels like implicit, but it should be explicit. Furthermore, I would have thought |
Beta Was this translation helpful? Give feedback.
-
Not a blocker to using Drizzle but I sometimes miss query scopes (ex: https://guides.rubyonrails.org/active_record_querying.html#scopes) Thank you for the hard work. |
Beta Was this translation helpful? Give feedback.
-
I can't wait anymore guys. Can you please tell us when a beta version of this will be available? I don't want to write V1 anymore after seeing this. Please. |
Beta Was this translation helpful? Give feedback.
-
Any ETA on this? Ive found it really hard to build paginated apis with drizzle query syntax because there is no way to count to total number for rows in that filter. Im using 3-4 layer deep relations so switching to .select() is not really a good option. |
Beta Was this translation helpful? Give feedback.
-
Would love to see some support for custom sql in the relation definitions, with the hope that I could realize a relation using JSON data with ids. |
Beta Was this translation helpful? Give feedback.
-
Hi Team, I'd like to use the query syntax for (sqlite) export const usersView = sqliteView("user_view").as((qb) => qb.select().from(users))
const resultWithQuerySyntax = dbWithDrizzle.query.usersView.findMany() // not possible atm 🫤
const resultWithSelectSyntax = dbWithDrizzle.select().from(usersView) // working as documented, but no support for querying relations via 'with' from the query syntax |
Beta Was this translation helpful? Give feedback.
-
We've launched Drizzle Relational Queries exactly a year ago and it's time to ship a fundamental upgrade. We've gathered a massive amount of valuable feedback from the community and going to address every issue, so if you have anything you're missing with Drizzle Queries - feel free to comment below!
Things we want to address:
Views
Relations declaration
Current implementation of Drizzle Relations has several major flaws - naming, imports, many to many relations,
where
clause and aggregation fields.Naming and imports
Our community’ve split into 2 groups - ones that don’t care and others who demand us to reduce the needs for imports whenever possible. We've been using drizzle in production projects and never paid attention or considered amount of imports an issue, we’re on first camp, but as of now we do consider imports to be a decent part of the DX. We took that into consideration while designing API v2.
As of naming - we've originally sticked to
fields
andreferences
and thought it'd be a good idea to stick to close-to-sql model here, but it turned out to be confusing for both the community and for us too! We've investigated implementations across different libraries and decided to land onone
,many
,from
,to
andthrough
for junction tables, they does seem to be the most natural out of all for both newcomers and for developers who're going to migrate to Drizzle.New API will let us support aggregation fields in schema declaration
Where clauses
As of V2 - relations declaration will be defined in one file and
relations
initialisation function will now requireschema
and will provide the best possible autocomplete experience with no need to import anything else from other filesWith this small restriction we can perfectly solve junction table declaration challenge:
and for composite keys
Filters API
While Drizzle was originally built as a SQL-like ORM, we quickly got to the point that we need to have best of both(sql and relational) worlds. We’ve introduced relational APIs with the least compromises possible. Based on the community feedback and by using our own library for a while on commercial production grade projects we do came to the conclusion to introduce object based filters for relational queries, it just feels natural
multiple filters are by default combined with
AND
operatoryou will be able to combine filters with
OR
andNOT
operatorscalar types will have either scalar value filter or advanced object filter
this API will let us easily introduce relational filters while keeping the option to declare
raw
sql filters for whatever cases we do not support on launch dayInteroperability and Docs
As of now
Queries
section of the docs is a zero to hero of Relational Queries and we will split it into two detailed sections onhow to declare relations
andhow to query
As of interop - we will add a legacy
drizzle._query
operator to establish a smoother transition on existing projects with the ability to either stay on legacy API or gradually migrateBeta Was this translation helpful? Give feedback.
All reactions