Skip to content

Commit 8e5766a

Browse files
committed
[Blog] Edit
1 parent 87ea764 commit 8e5766a

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

β€ŽBlog/blog/2025-08-15-sea-query-raw-sql.mdβ€Ž

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,13 @@ assert_eq!(query.values, Values(vec![1.into(), "2".into(), 3.into()]));
170170

171171
You may ask, then how do we insert multiple elements? Which brings us to the next feature:
172172

173-
## Repeating Group
173+
## Insert Many
174+
175+
When working with Rust and SQL, a common pain point is figuring out how to insert multiple rows efficiently. Writing raw SQL INSERT statements for each row is verbose, and while Postgres supports `UNNEST` for bulk inserts, its columnar API feels awkward and error-prone.
176+
177+
SeaQuery solves this by letting you build multi-row insert statements easily. With the `raw_query!` macro, you can pass in a vector of structs or tuples and generate a single `INSERT INTO .. VALUES (..) , (..) , (..)` query. This keeps your code clean, while still allowing you to do bulk insertions for efficiency. This solution is database agnostic so you can use it for MySQL and SQLite as well.
178+
179+
### With Tuples
174180

175181
```rust
176182
let values = vec![(1, "2", 3), (4, "5", 6)];
@@ -187,11 +193,11 @@ assert_eq!(
187193
);
188194
```
189195

190-
This syntax almost looks like regex now. Please let me explain:
196+
To achieve this we designed the "repeating group" syntax, inspired by regex. Please let me explain:
191197

192198
It's expanded upon the previous example, in which `values.0:2` means tuple expansion. We want to repeat this tuple as a group, surrounded by parenthesis, so we wrap it with `()`. Then we apply the same spread operator `..` to expand the vector of tuples. Finally, the trailing `,` means they should be connected with `,`.
193199

194-
This repeating group is not fully-generalized yet, but is quite flexible:
200+
### With structs
195201

196202
```rust
197203
struct Item {
@@ -212,7 +218,7 @@ let query = sea_query::raw_query!(
212218
);
213219
```
214220

215-
This is equivalent to the previous example.
221+
This is equivalent to the previous example, but uses named parameters.
216222

217223
## SQLx Integration
218224

@@ -246,7 +252,34 @@ let res = sea_query::sqlx::sqlite::query!(
246252

247253
Full example can be found [here](https://github.com/SeaQL/sea-query/blob/master/examples/sqlx_sqlite/src/main.rs).
248254

249-
It almost feels like a mini ORM ... although [SeaORM 🐚](https://github.com/SeaQL/sea-orm) is still highly recommended by us!
255+
It almost feels like a mini ORM ... although [SeaORM 🐚](https://github.com/SeaQL/sea-orm) is still highly recommended!
256+
257+
### Lightweightness
258+
259+
SeaQuery without default features only has a handful of dependencies. But if you want to keep dependencies to an absolute minimum, you can depends on `sea-query-derive` directly.
260+
261+
```sh
262+
$ cargo tree --no-default-features -e normal,build
263+
sea-query-derive v1.0.0-rc.11 (proc-macro)
264+
β”œβ”€β”€ proc-macro2 v1.0.94
265+
β”‚ └── unicode-ident v1.0.12
266+
β”œβ”€β”€ quote v1.0.40
267+
β”‚ └── proc-macro2 v1.0.94 (*)
268+
└── syn v2.0.100
269+
β”œβ”€β”€ proc-macro2 v1.0.94 (*)
270+
β”œβ”€β”€ quote v1.0.40 (*)
271+
└── unicode-ident v1.0.12
272+
```
273+
274+
Then you can use it like:
275+
276+
```rust
277+
let sql;
278+
let res: Vec<_> = sea_query_derive::raw_sql!(
279+
sqlx::sqlite::query_as,
280+
sql = "SELECT {var.0:2}"
281+
).fetch_all(pool).await?;
282+
```
250283

251284
## SeaQuery 1.0
252285

0 commit comments

Comments
Β (0)