Skip to content

Instantly share code, notes, and snippets.

@RishiSadhir
Last active February 25, 2016 15:54
Show Gist options
  • Save RishiSadhir/78754a5f3159ebd0df11 to your computer and use it in GitHub Desktop.
Save RishiSadhir/78754a5f3159ebd0df11 to your computer and use it in GitHub Desktop.
Turn a CSV in to SQL Insert Statements
(ns
^{:doc "Convert a CSV in to Oracle insert statements.
This program takes as input
1. A CSV. Some care is taken to remove whitespace and quotes from
elements of the CSV.
2. A tablename. The tablename is used to both name
the table we are inserting the csv in to as well as
the name of the sql file that is generated.
Returns a tablename.sql file full of insert statements."
:author "Rishi Sadhir"}
insertify-csv.core
(:require
[clojure.string :as str]
[clojure.java.io :as io])
(:gen-class))
(defn -main
[& args]
(csv->sql (first args) (second args)))
(defn csv->sql
"Convert a CSV into oracle insert statements.
Assumes the file has column headers."
[filename tablename]
(write-file
(map #(sqlify % tablename) (mapify (parse filename)))
(str tablename ".sql")))
(defn sqlify
"Turn a single map in to a SQL insert statements"
[row tablename]
(let [keys (keys row)
cols (map name keys)]
(str "INSERT INTO " tablename " ("(str/join "," cols)") \nVALUES (" (gen-values keys row) ");")))
(defn parse
"Convert a CSV in to a vector of vectors"
[filename]
(map #(str/split (str/trim %) #",")
(str/split (slurp filename) #"\n")))
(defn mapify
"Create a vector of maps keyed by the first row of a vector of vectors."
[data]
(let [col-names (map keyword
(format-row (first data)))
data (rest data)]
(map #(zipmap col-names (format-row %)) data)))
(defn- format-row
"Remove quotes, Trim, and Snake Case column names"
[row]
(map #(str/replace (str/trim (str/replace % #"[`'\"]+" "")) #"[-\s]+" "_") row))
(defn write-file
"Write a vector of strings to a new file"
[statements out]
(with-open [wrtr (io/writer out)]
(doseq [i statements]
(.write wrtr (str i "\n\n")))))
(defn- gen-values
"Comma separates a maps values as a single string"
[data-keys row]
(let [vals (reduce (fn [c v] (conj c (str "'"(v row) "'")))
[]
data-keys)]
(str/join "," vals)))
;(csv->sql "file.csv" "tablename")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment