   "Returns a [{<hash-key> KeySchemaElement}], or
              [{<hash-key> KeySchemaElement} {<range-key> KeySchemaElement}]
    vector for use as a table/index primary key."
-  [hash-keydef & [range-keydef]]
-  (let [schema [(key-schema-element (:name hash-keydef) :hash)]]
-    (if range-keydef
-      (conj schema (key-schema-element (:name range-keydef) :range))
-      schema)))
+  [{hash-key-name :name :as hash-keydef} &
+   [{range-key-name :name :as range-keydef}]]
+  (assert (and hash-key-name (when range-keydef range-key-name))
+          (assert (str "Malformed key schema: "
+                       {:hash-keydef  hash-keydef
+                        :range-keydef range-keydef})))
+  (cond-> [(key-schema-element hash-key-name :hash)]
+          range-keydef (conj (key-schema-element range-key-name :range))))
 
 (defn- provisioned-throughput "Returns a new ProvisionedThroughput object."
-  [{read-units :read write-units :write}]
+  [{read-units :read write-units :write :as throughput}]
+  (assert (and read-units write-units)
+          (str "Malformed throughput: " throughput))
   (doto (ProvisionedThroughput.)
     (.setReadCapacityUnits  (long read-units))
     (.setWriteCapacityUnits (long write-units))))

  [conditions]
  (when (seq conditions)
    (utils/name-map
     (fn [[operator values]]
       (doto (Condition.)
         (.setComparisonOperator (enum-op operator))
         (.setAttributeValueList (mapv clj-val->db-val values))))


(defn query
  "Retries items from a table (indexed) with options:
    prim-key-conds - {<key-attr> [<comparison-operator> <values>] ...}.
    :last-prim-kvs - primary key-val from which to eval, useful for paging.
    :return        - e/o #{:all-attributes :all-projected-attributes :count
                           [<attr> ...]}.
