Как позволить csvkit/csvsql генерировать операторы вставки для файла csv?

Я хочу сгенерировать SQL вставки для некоторых CSV-файлов.

Я могу сделать это с помощью однострочного скрипта awk, такого как:

awk -F "\t" '{printf("INSERT INTO T_COMMON_ENUM_VALUE (id,name,category_id) values (%s, '\''%s'\'', %s, %s);\n", $1, $2, $3, $4)}'

Но это все еще требует определенных усилий. Кажется, csvsql внутри csvkit генерирует операторы вставки автоматически. Я проверил документацию и использовал следующую команду, но она не генерирует операторы вставки.

$ cat data02.csv
db_enumvalue_id db_enumvalue_name       db_enumcategory_id
800     şirin   9

$ csvsql data02.csv
CREATE TABLE data02 (
        db_enumvalue_id INTEGER NOT NULL,
        db_enumvalue_name VARCHAR(18) NOT NULL,
        db_enumcategory_id INTEGER NOT NULL
);

Он генерирует операторы создания таблицы. Но в документации сказано:

Generate SQL statements for a CSV file or execute those statements directly on a database.

Что я должен сделать, чтобы получить инструкции SQL вставки с помощью csvkit?

4 ответа

Это полностью управляемый данными способ. Немного тупой, но это работает.

#!/usr/bin/env bash

##
## ensure script stops on errors
set -eu
set -o pipefail

##
## load your data into a SQLite DB
csvsql test.csv --db=sqlite:///test.db --insert

##
## let SQLite generate the inserts
echo ".dump test" | sqlite3 test.db

Запустите это, и вы получите что-то вроде:

BEGIN TRANSACTION;
CREATE TABLE test (
    id INTEGER NOT NULL,
    month VARCHAR(5) NOT NULL,
    market FLOAT NOT NULL,
    acme FLOAT NOT NULL
);
INSERT INTO "test" VALUES(1,'1/86',-0.061134,0.03016);
INSERT INTO "test" VALUES(2,'2/86',0.00822,-0.165457);
INSERT INTO "test" VALUES(3,'3/86',-0.007381,0.080137);
...
INSERT INTO "test" VALUES(60,'12/90',-0.026401,-0.190834);
COMMIT;

Захватите это в файл, и вы золотой. Также может быть заключен в вызов подпроцесса Python или передан в клиент командной строки базы данных, если вы также хотите автоматизировать этап вставки.

Если вы вставляете в существующую таблицу, этот подход подходит для СУБД, такой как MySQL, которая будет выполнять неявные преобразования типов, поскольку CSV не может определять типы данных для полей после строк и чисел.

Глядя на документацию, я думаю, что-то вроде этого:

если таблица назначения T_COMMON_ENUM_VALUE уже существует:

$ csvsql --tables T_COMMON_ENUM_VALUE --insert --no-create data02.csv

если таблица назначения T_COMMON_ENUM_VALUE не существует:

$ csvsql --tables T_COMMON_ENUM_VALUE --insert data02.csv

это должно только выводить скрипт, если вы хотите, чтобы операторы выполнялись в вашей БД, вам нужно добавить --db CONNECTION_STRING, например:

$ csvsql --db mssql://user:pass@host:port/database --tables T_COMMON_ENUM_VALUE --insert data02.csv

надеюсь, это поможет

Вероятно, не существует простого решения для создания сценария вставки или удаления сценария SQL с помощью csvsql; по крайней мере, я не мог найти его сам, когда мне это было крайне необходимо. Тем не менее --query Опция приходит нам на помощь, позволяя нам самим готовить такие заявления. Конечно, нужно немного усилий, но это окупается очень хорошо.

Вот пример. У меня есть CSV-файл (называется test2.csv). Вот как я могу генерировать операторы вставки для всех строк в файле CSV.

csvsql  --query "SELECT 'insert into test2  values (''' ||    
trim(ifnull(my_table.survived, 'null123')) ||''' ,''' ||     
trim(ifnull(my_table.RECORD_TYPE, 'null123')) ||''' ,''' ||     
trim(ifnull(my_table.BASE_HIN, 'null123')) ||''' ,''' ||     
trim(ifnull(my_table.SUFFIX, 'null123')) ||''',''' ||     
trim(ifnull(my_table.name, 'null123')) ||''' ,''' ||     
trim(ifnull(my_table.ADDRESS_1, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.ADDRESS_2, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.CITY, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.STATE, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.PRIMARY_ZIP, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.COUNTRY, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.TELEPHONE, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.CLASS_OF_TRADE, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.DEA, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.DATE_HIN_ASSIGNED, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.DATE_LAST_EDITED, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.STATUS, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.VERIFIED, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.LAST_ACTION_CODE, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.REASON_CODE, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.REFERBACK_CODE, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.SUBSET, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.UPIN, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.SPECIALTY, 'null123')) ||'''  ,''' ||     
trim(ifnull(my_table.FAX, 'null123')) ||''' )'FROM test2 as my_table WHERE survived='0'" test2.csv > insert.sql

Убедитесь, что это одна строка, потому что csvsql не любит ломаные линии.

Кроме того, как только insert.sql готов, вам нужно удалить строку заголовка, удалить двойные кавычки (из всех строк), а также найти и заменить = 'null123' с is null,

https://github.com/Ахмед-М-Салах/CsvToSql

Проект AC#. Обновленный форк предыдущего проекта 5-7-летней давности.

Другие вопросы по тегам