Batching
PrismaClient::_batch allows you to sequentially execute multiple queries in a single transaction.
If one of the queries fails, all changes will be rolled back.
Data provided to _batch falls under two categories:
- 
Containers: Root level collections that contain all items in the batch. Can be either a tuple or a type implementing
IntoIter. - 
Items: Either a query or a collection (
Vecor tuple) of nested queries. 
Containers
Even if your batch doesn't include nested items, you still need to put queries inside some sort of container.
Tuple
Using a tuple allows for multiple types of queries to be used at once.
The return type of _batch will be a tuple of the results of each item.
use prisma::user;
 
let (user_one, user_two, user_count): (user::Data, user::Data, i64) = client
    ._batch((
        client.user().create(..),
        client.user().create(..),
        client.user().count(vec![]),
    ))
    .await?;
 
assert_eq!(user_count, 2);Iterator
Using a type that implements IntoIter such as Vec allows for
a dynamic number of items to be batched together.
The return type will be a Vec of the result of the item.
use prisma::user;
 
let users: Vec<user::Data> = client
    ._batch(vec![
        client.user().create(..),
        client.user().create(..),
        client.user().create(..)
    ])
    .await?;
 
assert_eq!(users.len(), 3);IntoIter includes regular iterators,
so you can pass them straight into _batch and
collect will be called internally.
use prisma::user;
 
let user_ids = vec![1, 2, 3, 4, 5];
 
let user_creates = user_ids
    .into_iter()
    .map(|id| client
        .user()
        .create(..)
    ); // _batch will collect internally!
 
let users: Vec<user::Data> = client
    ._batch(user_creates)
    .await?;
 
assert_eq!(users.len(), 5);Items
Items can be either individual queries or a collection.
Tuple
The same logic applies to a tuple item as a tuple container, with the item's result being a 1-1 mapping of each query to its result type.
let data: Vec<(user::Data, post::Data)> = client
	._batch(vec![
		(client.user().create(..), client.post().create(..)),
		(client.user().create(..), client.post().create(..)),
	])
	.await?;Vec
Unlike containers, only Vec can be used for dynamic collections of queries.
Apart from that, the behaviour is the same.
let data: (Vec<user::Data>, Vec<post::Data>) = client
	._batch((
		vec![client.user().create(..), client.user().create(..)],
		vec![client.post().create(..), client.post().create(..)],
	))
	.await?;Nesting
Any combination and nesting of items can be put inside a container, allowing for heavily nested return types.
This example isn't really practical, but it's possible.
let data: Vec<(
	Vec<(user::Data, post::data)>,
	(Vec<user::Data>, Vec<post::Data>),
)> = client._batch(vec![(
	vec![
		(client.user().create(..), client.post.create(..)),
		(client.user().create(..), client.post.create(..)),
	],
	(vec![client.user().create(..)], vec![client.post.create(..)]),
)]);