CSV vers SQL
Générez des instructions SQL INSERT à partir de données CSV
Entrée CSV
Sortie SQL
Qu'est-ce que la conversion CSV vers SQL ?
La conversion CSV vers SQL transforme des valeurs séparées par des virgules en instructions SQL que peut exécuter une base de données relationnelle. Le résultat le plus courant est un couple : une instruction CREATE TABLE qui définit les colonnes, et une ou plusieurs instructions INSERT INTO qui peuplent ces colonnes avec les lignes du fichier CSV.
Les fichiers CSV suivent la spécification RFC 4180. Chaque ligne correspond à un enregistrement, les champs sont séparés par un délimiteur (généralement une virgule), et les champs contenant le délimiteur ou des sauts de ligne sont encadrés de guillemets doubles. SQL, quant à lui, est le langage standard pour gérer les données dans des systèmes comme PostgreSQL, MySQL, SQLite et SQL Server. La conversion entre ces deux formats est l'une des tâches d'import de données les plus fréquentes en développement logiciel.
Un convertisseur CSV vers SQL digne de ce nom gère les guillemets, échappe les apostrophes dans les valeurs (en les doublant en '' selon la norme SQL), associe les en-têtes de colonnes à des identifiants SQL valides, et peut optionnellement inférer les types de données. Au-delà de l'échappement basique, un bon convertisseur normalise les noms d'en-têtes (en remplaçant les espaces et les tirets par des underscores) et encapsule la sortie dans un bloc de transaction, de sorte qu'un échec d'import effectue un rollback propre plutôt que de laisser des données partielles dans la table. Sans convertisseur, écrire manuellement des instructions INSERT pour quelques centaines de lignes est fastidieux et source d'erreurs.
Pourquoi utiliser un convertisseur CSV vers SQL ?
Rédiger des instructions SQL INSERT à la main à partir de données issues d'un tableur est fastidieux et source d'erreurs de syntaxe. Un convertisseur automatise les parties répétitives pour que vous puissiez vous concentrer sur la conception du schéma et la validation des données.
Cas d'usage du convertisseur CSV vers SQL
Référence des types de données SQL
Lors de la conversion CSV vers SQL, toutes les colonnes sont par défaut de type TEXT car CSV ne contient pas de métadonnées de type. Si vous connaissez les types de vos colonnes, vous pouvez remplacer TEXT dans la sortie CREATE TABLE. Ce tableau présente les types SQL les plus courants et leur utilisation.
| Type | Utilisé pour | Notes |
|---|---|---|
| TEXT / VARCHAR | Strings, mixed content | Default safe choice; works in every SQL dialect |
| INTEGER / INT | Whole numbers (age, count, ID) | Use when column contains only digits with no decimals |
| REAL / FLOAT | Decimal numbers (price, rate) | Needed for columns with dots like 19.99 or 3.14 |
| DATE | ISO 8601 dates (2024-01-15) | Requires consistent formatting; varies by database |
| BOOLEAN | true/false, 1/0, yes/no | MySQL uses TINYINT(1); PostgreSQL has native BOOL |
| NUMERIC / DECIMAL | Exact precision (currency) | Specify scale: DECIMAL(10,2) for money columns |
| BLOB / BYTEA | Binary data | Rarely needed in CSV imports; use for hex-encoded fields |
Comparaison des dialectes SQL
La syntaxe SQL varie selon les moteurs de base de données. Les instructions INSERT générées utilisent du SQL standard qui fonctionne dans la plupart des systèmes, mais certaines fonctionnalités diffèrent. Ce tableau résume les différences les plus importantes lors de l'import de données CSV.
| Fonctionnalité | PostgreSQL | MySQL | SQLite | SQL Server |
|---|---|---|---|---|
| Identifier quoting | "col" | `col` | "col" | [col] |
| String escape | '' | '' or \' | '' | '' |
| INSERT syntax | INSERT INTO | INSERT INTO | INSERT INTO | INSERT INTO |
| Batch INSERT | VALUES (),()… | VALUES (),()… | VALUES (),()… | max 1000 rows |
| Auto-increment | SERIAL | AUTO_INCREMENT | AUTOINCREMENT | IDENTITY(1,1) |
| Upsert / merge | ON CONFLICT | ON DUPLICATE KEY | ON CONFLICT | MERGE |
| NULL handling | IS NULL | IS NULL / <=> | IS NULL | IS NULL |
| COPY from CSV | COPY … FROM | LOAD DATA INFILE | .import | BULK INSERT |
INSERT vs COPY : choisir une méthode d'import
Pour les jeux de données petits à moyens (moins de 10 000 lignes), les instructions INSERT fonctionnent bien et sont portables sur tous les systèmes SQL. Pour les imports volumineux, les bases de données proposent des commandes de chargement en masse qui contournent entièrement l'analyseur SQL.
Exemples de code
Ces exemples montrent comment convertir du CSV en instructions SQL INSERT dans différents langages. Chacun gère l'échappement des apostrophes et l'assainissement des noms de colonnes.
// CSV → SQL INSERT statements
const csv = `name,age,city
Alice,30,Berlin
Bob,25,Tokyo`
function csvToSql(csv, table = 'data') {
const rows = csv.trim().split('\n').map(r => r.split(','))
const [headers, ...data] = rows
const cols = headers.map(h => h.trim().toLowerCase().replace(/\s+/g, '_'))
const values = data.map(row =>
' (' + row.map(v => `'${v.replace(/'/g, "''").trim()}'`).join(', ') + ')'
)
return `INSERT INTO ${table} (${cols.join(', ')}) VALUES
${values.join(',\n')};`
}
console.log(csvToSql(csv, 'users'))
// → INSERT INTO users (name, age, city) VALUES
// ('Alice', '30', 'Berlin'),
// ('Bob', '25', 'Tokyo');import csv
import io
csv_string = """name,age,city
Alice,30,Berlin
Bob,25,Tokyo"""
reader = csv.reader(io.StringIO(csv_string))
headers = [h.strip().lower().replace(' ', '_') for h in next(reader)]
table = 'users'
rows = list(reader)
# CREATE TABLE
col_defs = ', '.join(f'{h} TEXT' for h in headers)
print(f'CREATE TABLE {table} ({col_defs});')
# → CREATE TABLE users (name TEXT, age TEXT, city TEXT);
# INSERT statements
for row in rows:
vals = ', '.join(f"'{v.replace(chr(39), chr(39)*2)}'" for v in row)
print(f"INSERT INTO {table} ({', '.join(headers)}) VALUES ({vals});")
# → INSERT INTO users (name, age, city) VALUES ('Alice', '30', 'Berlin');
# → INSERT INTO users (name, age, city) VALUES ('Bob', '25', 'Tokyo');package main
import (
"encoding/csv"
"fmt"
"strings"
)
func csvToSQL(data, table string) string {
r := csv.NewReader(strings.NewReader(data))
records, _ := r.ReadAll()
if len(records) < 2 {
return ""
}
headers := records[0]
var vals []string
for _, row := range records[1:] {
escaped := make([]string, len(row))
for i, v := range row {
escaped[i] = "'" + strings.ReplaceAll(v, "'", "''") + "'"
}
vals = append(vals, " ("+strings.Join(escaped, ", ")+")")
}
return fmt.Sprintf("INSERT INTO %s (%s) VALUES\n%s;",
table, strings.Join(headers, ", "), strings.Join(vals, ",\n"))
}
func main() {
csv := "name,age,city\nAlice,30,Berlin\nBob,25,Tokyo"
fmt.Println(csvToSQL(csv, "users"))
// → INSERT INTO users (name, age, city) VALUES
// ('Alice', '30', 'Berlin'),
// ('Bob', '25', 'Tokyo');
}# SQLite: import CSV directly into a table sqlite3 mydb.db <<EOF .mode csv .import data.csv users SELECT * FROM users LIMIT 5; EOF # PostgreSQL: COPY from CSV file (server-side) psql -c "COPY users FROM '/path/to/data.csv' WITH (FORMAT csv, HEADER true);" # PostgreSQL: \copy from CSV (client-side, no superuser needed) psql -c "\copy users FROM 'data.csv' WITH (FORMAT csv, HEADER true);" # MySQL: LOAD DATA from CSV mysql -e "LOAD DATA INFILE '/path/to/data.csv' INTO TABLE users FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;"