      (doto-maybe (KeysAndAttributes.) g
        attrs       (.setAttributesToGet (mapv name g))
        consistent? (.setConsistentRead  g)
-       :always     (.setKeys (multi-kvs prim-kvs))))
+       :always     (.setKeys (attr-multi-vs prim-kvs))))
    requests))
 
 (comment (batch-request-items {:my-table {:prim-kvs [{:my-hash  ["a" "b"]

          (fn [table-request]
            (reduce into []
             (for [action (keys table-request)
                   :let [items (multi-kvs (table-request action))]]
               (mapv (partial write-request action) items))))
          requests))))))



;;;; API - batch ops

(defn- attr-multi-vs
  "[{<attr> <v-or-vs*> ...} ...]* -> [{<attr> <v> ...} ...] (* => optional vec)"
  [attr-multi-vs-map]
  (let [ensure-coll (fn [x] (if (coll?* x) x [x]))]
    (reduce (fn [r attr-multi-vs]
              (let [attrs (keys attr-multi-vs)
                    vs    (mapv ensure-coll (vals attr-multi-vs))]
                (when (> (count (filter next vs)) 1)
                  (-> (Exception. "Can range over only a single attr's values")
                      (throw)))
                (into r (mapv (comp clj-item->db-item (partial zipmap attrs))
                              (apply utils/cartesian-product vs)))))
            [] (ensure-coll attr-multi-vs-map))))

(comment (attr-multi-vs {:a "a1" :b ["b1" "b2" "b3"] :c ["c1" "c2"]})
         (attr-multi-vs {:a "a1" :b ["b1" "b2" "b3"] :c ["c1"]}))

(defn- batch-request-items
  "{<table> <request> ...} -> {<table> KeysAndAttributes> ...}"
