Как позволить 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-летней давности.