Глава 4. Выполнение кода MySQL Shell

Эта секция объясняет, как выполнение кода работает в MySQL Shell.

4.1. Активный язык

MySQL Shell может выполнить SQL, JavaScript или Python, но только один язык может быть активным за один раз. Активный режим определяет, как выполненные запросы обрабатываются:

Когда MySQL Shell работает в интерактивном режиме, активируйте определенный язык командами: \sql, \js или \py.

Когда MySQL Shell работает в пакетном режиме, активируйте определенный язык, передав любой из этих параметров командной строки: --js , --py или --sql . Режимом по умолчанию, если ни один не определяется, является JavaScript.

Используйте MySQL Shell, чтобы выполнить содержание файла code.sql как SQL.

shell> mysqlsh --sql < code.sql

Используйте MySQL Shell, чтобы выполнить содержание файла code.js как JavaScript.

shell> mysqlsh < code.js

Используйте MySQL Shell, чтобы выполнить содержание файла code.py как Python.

shell> mysqlsh --py < code.py

С MySQL Shell 8.0.16 можно выполнить единственный SQL-оператор в то время, как другой язык активен, вводя команду \sql немедленно сопровождаемую SQL-оператором. Например:

\sql select * from sakila.actor limit 3;

Для SQL-оператора не нужно никакое дополнительное цитирование и дополнительный разделитель запросов. Команда принимает только единственный SQL-запрос на одной строке. С этим форматом MySQL Shell не переключает режим, как это было бы, если вы вводите \sql. После того, как SQL-оператор был выполнен, MySQL Shell остается в режиме JavaScript или Питона.

4.2. Интерактивное выполнение кода

Режим по умолчанию MySQL Shell обеспечивает интерактивное выполнение операций по базе данных, которые вы печатаете в командной строке. Эти операции могут быть написаны на JavaScript, Питоне или SQL, в зависимости от текущего режима. Когда выполнено, результаты операции показаны на экране.

Как с любым другим языковым интерпретатором, MySQL Shell очень строг относительно синтаксиса. Например, следующий отрывок JavaScript открывает сессию для сервера MySQL, затем читает и печатает документы в коллекции:

var mySession = mysqlx.getSession('user:pwd@localhost');
var result = mySession.world_x.countryinfo.find().execute();
var record = result.fetchOne();

while(record)
{
   print(record);
   record = result.fetchOne();
}

Как замечено выше, вызов find() сопровождается функцией execute(). Команды базы данных CRUD на самом деле выполняются на MySQL Server только когда вызвана execute(). Однако, работая с MySQL Shell в интерактивном режиме, execute() неявно вызвана каждый раз, когда вы нажимаете Return. Тогда результаты операции получены и показаны на экране. Правила для того, когда необходимо вызвать execute() или нет, следующие:

На основе вышеупомянутых правил, запросы в MySQL Shell должны были в интерактивном режиме установить сессию, запросить и напечатать документы в коллекции:

mysql-js> var mySession = mysqlx.getSession('user:pwd@localhost');

Никакого вызова execute() не надо, объект результата автоматически печатается.

mysql-js> mySession.world_x.countryinfo.find();

Многострочная поддержка

Возможно определить запросы на нескольких строках. В режиме Python или JavaScript этот способ автоматически включен, когда блок запросов начинается как в определениях функции, условных операторах, циклов и т.п. В режиме SQL многострочный формат начинается, когда выдана команда \.

Как только многострочный режим начат, впоследствии введенные запросы кэшируются.

Например:

mysql-sql> \
... create procedure get_actors()
... begin
... select first_name from sakila.actor;
... end
...
mysql-sql>

Вы не можете использовать многострочный режим, когда вы используете команду \sql с запросом, чтобы выполнить единственный SQL-оператор в то время, как другой язык активен. Команда принимает только единственный SQL-запрос на одной строке.

4.3. Автозавершение кода

MySQL Shell поддерживает автозавершение текста, предшествующего курсору, нажимая Tab. Команда может быть автоматически заполнена в любом из языковых режимов. Например, ввод \con и нажатие Tab автоматически заполняет \connect. Автозавершение доступно для языковых ключевых слов SQL, JavaScript и Python в зависимости от текущего активного языка в приложении.

Автозавершение поддерживает следующие текстовые объекты:

По умолчанию автозавершение позволено, чтобы изменить это поведение, посмотрите про настройку автозавершения.

Как только вы активируете автозавершение, если у текста, предшествующего курсору, есть точно одно возможное соответствие, текст автоматически закончен. Если автозавершение находит многократные возможные соответствия, оно сигналит. Если Tab нажат снова, будет показан список возможных завершений. Если никакое соответствие не найдено, никакого автозавершения не происходит.

Автоматическое заполнение SQL

Когда MySQL Shell в режиме SQL, автозавершение пытается закончить любое слово со всеми возможными завершениями. В SQL может быть автоматически заполнено следующее:

Как специальное исключение, если обратный апостроф найден, только имена таблиц рассматривают для завершения. В режиме SQL автозавершение не учитывает контекст, означая, что нет никакой фильтрации завершений на основе грамматики SQL. Другими словами, автоматическое заполнение SEL вернет SELECT, но это могло также включать таблицу selfies.

Автоматически заполнение JavaScript и Python

В режимах JavaScript и Python последовательность, которая будет закончена, определяется справа налево, начинаясь в текущей позиции курсора, когда нажата Tab. Содержание в вызовах метода проигнорировано, но должно быть синтаксически правильным. Это означает, что последовательности, комментарии и вложенные вызовы метода должны все быть правильно закрыты и уравновешены. Это позволяет методам быть обработанными правильно. Например, когда вы вводите:

print(db.user.select().where("user in ('foo', 'bar')").e
нажатие Tab заставило бы автозавершение пытаться закончить текст db.user.select().where().e, но этот недействительный код приводит к неопределенному поведению. Любой пробел, включая новые строки, между символами, отделенными ., проигнорирован.

Настройка автозавершения

По умолчанию автозавершение позволено. Эта секция объясняет, как отключить автозавершение и использовать команду \rehash MySQL Shell. Автозавершение использует кэш объектов имен базы данных, о которых знает MySQL Shell. Когда автозавершение позволено, этот кэш автоматически обновляется. Например, каждый раз, когда вы загружаете схему, движок автозавершения обновляет кэш на основе текстовых объектов, найденных в схеме, чтобы можно было автоматически заполнить имена таблиц и так далее.

Чтобы отключить это поведение, вы можете:

Когда кэш автозавершения выключен, можно вручную обновить автозавершение текстовых объектов командой \rehash. вызывает перезагрузку кэша имен на основе текущей активной схемы.

Чтобы отключить автозавершение в то время, как MySQL Shell работает, используют следующие ключи shell.options:

Оба ключа устанавливаются в true по умолчанию и в false, если использована опция --no-name-cache. Чтобы изменить кэширование автозавершения имен для SQL в то время, как работает MySQL Shell, надо:

shell.options['autocomplete.nameCache']=true

Используйте \rehash, чтобы обновить кэш имен вручную.

Чтобы изменить кэширование автозавершения имен для JavaScript и Python в то время, как работает MySQL Shell, надо:

shell.options['devapi.dbObjectHandles']=true

Снова можно использовать \rehash, чтобы обновить кэш имен вручную.

4.4. Кодовая история MySQL Shell

Код, который вы вводите в MySQL Shell, сохранен в истории, к которой можно получить доступ, используя клавиши вверх и вниз. Можно также искать историю, используя функцию поиска истории. Чтобы искать по истории, используйте Ctrl+R, чтобы искать назад или Ctrl+S, чтобы искать вперед. Как только поиск активен, он ищет символы любых последовательностей, которые соответствуют им в истории, и показывает первое совпадение. Используйте Ctrl+S или Ctrl+R, чтобы искать дальнейшие соответствия текущему критерию поиска. Ввод большего количества знаков совершенствует поиск. Во время поиска можно нажать клавиши курсора, чтобы двигаться по истории с текущего результата поиска. Нажмите Enter, чтобы принять показанный вариант. Используйте Ctrl+C , чтобы отменить поиск.

Параметр конфигурации shell.options["history.maxSize"]=number определяет максимальное число записей, чтобы сохранить в истории. По умолчанию 1000. Если количество записей истории превышает максимум, самые старые записи удалены. Если максимум установлен в 0, никакие записи истории не сохранены.

Записи истории записаны в ~/.mysqlsh/history в Linux и Mac или в %AppData%\MySQL\mysqlsh\history в Windows. Пользовательский путь конфигурации может быть отвергнут на всех платформах, определив переменную окружения MYSQLSH_USER_CONFIG_HOME. Значение этой переменной заменяет %AppData%\MySQL\mysqlsh\ в Windows или ~/.mysqlsh/ в Unix. Файл истории создается автоматически MySQL Shell и читаем только владельцем. Если файл истории не может быть прочитан или записан, MySQL Shell регистрирует сообщение об ошибке и пропускает операцию чтения или записи.

Команда MySQL Shell \history показывает записи истории в порядке ввода вместе с их номером записи, который может использоваться с командой \history delete entry_number. Можно вручную удалить отдельные записи истории, указанный числовой диапазон записей истории или хвост истории. Можно также использовать \history clear, чтобы удалить всю историю вручную. Когда вы выходите из MySQL Shell, если опция shell.options["history.autoSave"] = true, записи истории, которые остаются в файле истории, сохранены и их нумерация перезагружается, чтобы начаться с 1. Если опция shell.options["history.autoSave"] = false, что является значением по умолчанию, файл истории очищен.

Только код, который вы печатаете в интерактивном режиме в ответ на приглашение MySQL Shell, добавляется к истории. Код, который выполняется косвенно или внутренне, например, когда выполнена команда \source, не добавляется к истории. Когда вы вводите многострочную команду, символы новой строки исчезают из записи истории. Если тот же самый код введен многократно, он сохранен в истории только однажды, уменьшив дублирование.

Можно настроить записи, которые добавляются к истории, используя опцию --histignore. Кроме того, используя MySQL Shell в режиме SQL, можно формировать последовательности, которые не должны быть добавлены к истории. Этот черный список истории также применяется, когда вы используете \sql, чтобы выполнить единственные SQL-операторы в то время, как другой язык активен.

Последовательности, которые соответствуют образцам IDENTIFIED или PASSWORD по умолчанию не добавляются к истории. Чтобы формировать дальнейшие последовательности, используйте опцию --histignore или shell.options["history.sql.ignorePattern"]. Многократные строки могут быть определены через двоеточие (:). Соответствие истории использует нечувствительный к регистру образец. Поддержаны подстановочные знаки * (соответствует каким-либо 0 или больше знакам) и ? (соответствует точно 1 символу). Последовательности по умолчанию определяются как "*IDENTIFIED*:*PASSWORD*".

Обратите внимание на то, что независимо от набора фильтров в черном списке истории, последний выполненный запрос всегда доступен, нажимая стрелки, чтобы можно было сделать исправления, не перепечатывая его. Если фильтрация относится к последнему выполненному запросу, он удален из истории, как только введен другой запрос, или если вы немедленно выходите из MySQL Shell после выполнения запроса.

4.5. Пакетное выполнение кода

MySQL Shell обеспечивает пакетное выполнение кода из:

Как альтернатива пакетному выполнению можно также управлять MySQL Shell из терминала, см. раздел 4.7.

В пакетном режиме вся логика команды, рассмотренная в разделе 4.2 недоступна, только действительный код для активного языка может быть выполнен. Обрабатывая код SQL, это выполняет запросы пошагово, используя следующую логику: прочитать/обработать/напечатать результат. Обрабатывая код не SQL, это загружает его полностью из входного источника и выполняет как одно целое. Используйте опцию --interactive (или -i ), чтобы настроить MySQL Shell, чтобы обработать входной источник, как будто это выполняется в интерактивном режиме. Такой подход активирует все опции, обеспеченные интерактивным режимом, который будет использоваться в пакетной обработке данных.

В этом случае, независимо от источника, он прочитан построчно и обработан с использованием интерактивного трубопровода.

Ввод обрабатывается на основе текущего языка программирования, выбранного в MySQL Shell, который по умолчанию JavaScript. Можно изменить язык программирования по умолчанию, используя опцию defaultMode. Файлы с расширениями .js, .py и .sql всегда обрабатываются в соответствующем языковом режиме, независимо от языка программирования по умолчанию.

Этот пример показывает, как загрузить код JavaScript из файла для пакетной обработки данных:

shell> mysqlsh --file code.js

Здесь файл JavaScript перенаправляется к стандартному вводу для выполнения:

shell> mysqlsh < code.js

Этот пример показывает, как перенаправить код SQL к стандартному вводу для выполнения:

shell> echo "show databases;" | mysqlsh --sql --uri user@192.0.2.20:33060

Выполнимые скрипты

В Linux можно создать выполнимые скрипты, которые работают с MySQL Shell включением строки #! как первой строки. Эта строка должна предоставить полный путь к MySQL Shell и включать опцию --file:

#!/usr/local/mysql-shell/bin/mysqlsh --file
print("Hello World\n");

Файл скрипта должен быть отмечен как исполняемый в файловой системе. Запуск скрипта вызывает MySQL Shell и выполняет содержание скрипта.

4.6. Выходные форматы

MySQL Shell может напечатать результаты в форматах таблицы, разделенном табуляцией, вертикальном или JSON. С MySQL Shell 8.0.14 опция resultFormat может использоваться, чтобы определить любой из этих выходных форматов как постоянный для всех сессий или только для текущей сессии. Изменение этого выбора немедленно вступает в силу. Для инструкций, как установить параметры конфигурации MySQL Shell, смотрите раздел 8.4. Альтернативно, параметр командной строки --result-format или его псевдонимы ( --table, --tabbed, --vertical) может использоваться при запуске, чтобы определить выходной формат для сессии. Для списка параметров командной строки посмотрите раздел A.1.

Если опция resultFormat не была определена, когда MySQL Shell находится в интерактивном режиме, формат по умолчанию для печати набора результатов является отформатированной таблицей, а когда MySQL Shell находится в пакетном режиме, формат по умолчанию для печати набора результатов является разделенным табуляциями. Когда вы устанавливаете умолчание, используя опцию resultFormat, это умолчание применяется в интерактивном и в пакетном режимах.

Чтобы помочь объединить MySQL Shell с внешними инструментами, можно использовать опцию --json, чтобы управлять JSON для всего вывода MySQL Shell, когда вы запускаете MySQL Shell из командной строки. Когда обертывание JSON включено, MySQL Shell производит красивый JSON или сырой JSON и значение опции resultFormat проигнорировано. Когда обертывание JSON выключают или не затребовали для сессии, наборы результатов произведены в формате, определенном опцией resultFormat.

Опция outputFormat устарела. Эта опция объединила обертывание JSON и функции печати результата. Если это все еще определяется в вашем конфигурационном файле MySQL Shell или скриптах, делается следующее:

4.6.1. Формат таблицы

Формат таблицы используется по умолчанию для печати наборов результатов, когда MySQL Shell находится в интерактивном режиме. Результаты запроса представлены как отформатированная таблица для лучшего вида и чтобы помочь анализу.

Чтобы получить этот выходной формат, работая в пакетном режиме, запустите MySQL Shell с опцией --result-format=table (или псевдонимом --table) или задайте параметр конфигурации resultFormat как table.

mysql-sql> select * from sakila.actor limit 3;
+----------+-------------+----------+--------------------+
| actor_id | first_name| l ast_name | last_update        |
+----------+-------------+----------+--------------------+
| 1        | PENELOPE    | GUINESS  | 2006-02-15 4:34:33 |
| 2        | NICK        | WAHLBERG | 2006-02-15 4:34:33 |
| 3        | ED          | CHASE    | 2006-02-15 4:34:33 |
+----------+-------------+----------+--------------------+
3 rows in set (0.00 sec)

mysql-sql>

4.6.2. Формат с символами табуляции

Этот формат используется по умолчанию для печати наборов результатов, когда MySQL Shell работает в пакетном режиме, чтобы произвести лучший вывод для автоматизированного анализа.

Чтобы получить этот выходной формат, работая в интерактивном режиме, запустите MySQL Shell с опцией --result-format=tabbed (или псевдонимом --tabbed) или установите параметр конфигурации MySQL Shell resultFormat в tabbed.

>echo "select * from sakila.actor limit 3;" | mysqlsh --classic --uri user@192.0.2.20:33460
actor_idfirst_namelast_name last_update
1 PENELOPE GUINESS 2006-02-15 4:34:33
2 NICK WAHLBERG 2006-02-15 4:34:33
3 ED CHASE 2006-02-15 4:34:33

4.6.3. Вертикальный формат

Вертикальный формат печатает наборы результатов вертикально вместо горизонтальной таблицы, таким же образом как когда используется терминатор запроса \G для запроса SQL. Вертикальный формат более удобочитаемый там, где есть более длинные текстовые строки.

Чтобы получить этот выходной формат, запустите MySQL Shell с опцией --result-format=vertical (или ее псевдонимом --vertical) или установите параметр конфигурации MySQL Shell resultFormat в vertical.

4.6.4. Формат вывода JSON

Параметры формата JSON печатают наборы результатов как любой сырой JSON (json/raw) или красивый JSON (json). Чтобы получить этот выходной формат, запустите MySQL Shell с опцией --result-format=json (для красивого JSON) или с --result-format=json/raw или установите параметр конфигурации MySQL Shell resultFormat в json (для красивого JSON) или в json/raw.

В пакетном режиме, чтобы помочь объединить MySQL Shell с внешними инструментами, можно использовать опцию --json, чтобы управлять JSON для всего вывода, когда вы запускаете MySQL Shell из командной строки. Когда обертывание JSON включено, MySQL Shell производит по умолчанию красивый JSON, значение опции resultFormat проигнорировано. Для инструкций посмотрите раздел 4.6.5.

Формат JSON (красивый) в интерактивном режиме

mysql-sql> select * from sakila.actor limit 3;
{
"duration": "0.00 sec",
"info": "",
"row_count": 3,
"rows": [
[
1,
"PENELOPE",
"GUINESS",
{
"year": 2006,
"month": 1,
"day": 15,
"hour": 4,
"minute": 34,
"second": 33.0
}
],
[
2,
"NICK",
"WAHLBERG",
{
"year": 2006,
"month": 1,
"day": 15,
"hour": 4,
"minute": 34,
"second": 33.0
}
],
[
3,
"ED",
"CHASE",
{
"year": 2006,
"month": 1,
"day": 15,
"hour": 4,
"minute": 34,
"second": 33.0
}
]
],
"warning_count": 0
}

mysql-sql>

Сырой формат JSON в интерактивном режиме

mysql-sql> select * from sakila.actor limit 3;
{"duration":"0.00 sec","info":"","row_count":3,"rows":[[1,"PENELOPE","GUINESS",{"year":2006,"month":1,"day":15,"hour":4,"minute":34,"second":33.0}],[2,"NICK","WAHLBERG",{"year":2006,"month":1,"day":15,"hour":4,"minute":34,"second":33.0}],[3,"ED","CHASE",{"year":2006,"month":1,"day":15,"hour":4,"minute":34,"second":33.0}]],"warning_count":0}

mysql-sql>

4.6.5. Обертка JSON

Чтобы помочь объединить MySQL Shell с внешними инструментами, можно использовать опцию --json, чтобы управлять JSON, когда вы запускаете MySQL Shell из командной строки. Опция --json вступает в силу только для сессии, для которой определяется.

Определение --json, --json=pretty или --json=raw включает JSON для сессии. С --json=pretty или без указанного значения генерируется красивый JSON. С --json=raw генерируется сырой JSON.

Когда обертывание JSON включено, любое значение, которое было определено для опции resultFormat в конфигурационном файле или в командной строке (опцией --result-format) проигнорировано.

Определение --json=off выключает JSON для сессии. Когда обертывание JSON выключают или не затребовали для сессии, наборы результатов произведены в формате, определенном опцией resultFormat.

Вывод MySQL Shell с JSON

shell>echo "select * from sakila.actor limit 3;" | mysqlsh --json=raw --sqlc --uri user@192.0.2.20:3306
{"duration":"0.00 sec","info":"","row_count":3,"rows":[[1,"PENELOPE","GUINESS",{"year":2006,"month":1,"day":15,"hour":4,"minute":34,"second":33.0}],[2,"NICK","WAHLBERG",{"year":2006,"month":1,"day":15,"hour":4,"minute":34,"second":33.0}],[3,"ED","CHASE",{"year":2006,"month":1,"day":15,"hour":4,"minute":34,"second":33.0}]],"warning_count":0}

shell>echo "select * from sakila.actor limit 3;" | mysqlsh --json --sqlc --uri user@192.0.2.20:3306
или
shell>echo "select * from sakila.actor limit 3;" | mysqlsh --json=pretty --sqlc --uri user@192.0.2.20:3306
{
"duration": "0.00 sec",
"info": "",
"row_count": 3,
"rows": [
[
1,
"PENELOPE",
"GUINESS",
{
"year": 2006,
"month": 1,
"day": 15,
"hour": 4,
"minute": 34,
"second": 33.0
}
],
[
2,
"NICK",
"WAHLBERG",
{
"year": 2006,
"month": 1,
"day": 15,
"hour": 4,
"minute": 34,
"second": 33.0
}
],
[
3,
"ED",
"CHASE",
{
"year": 2006,
"month": 1,
"day": 15,
"hour": 4,
"minute": 34,
"second": 33.0
}
]
],
"warning_count": 0
}
shell>

4.6.6. Метаданные результата

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

Когда формат JSON используется для вывода, метаданные возвращены как часть объекта JSON. В интерактивном режиме метаданные печатаются после результатов.

4.7. Интерфейс командной строки API

MySQL Shell выставляет большую часть своей функциональности, используя синтаксис команды API, который позволяет вам легко объединить mysqlsh с другими инструментами. Эта функциональность подобна использованию опции --execute, но интерфейс команды использует упрощенный синтаксис, который уменьшает цитирование и возможность экранировки, которая может требоваться терминалами. Например, если вы хотите создать кластер InnoDB, используя скрипт для bash, вы могли бы использовать эту функциональность. Следующие объекты MySQL Shell доступны:

Синтаксис интеграции командной строки API

Когда вы запускаете MySQL Shell в командной строке, используя следующий специальный синтаксис, -- указывает на конец списка вариантов после того, как это будут рассматривать как команду и ее аргументы.

mysqlsh [options] -- shell_object
        object_method
        [arguments]

Где следующее применяется:

shell_object должен соответствовать одному из выставленных глобальных объектов, и object_method должен соответствовать одному из методов глобального объекта в одном из допустимых форматов (JavaScript, Python или дружественная командная строка). Если они не соответствуют действительному глобальному объекту и его методам, MySQL Shell завершается с кодом 10.

Синтаксис аргумента интеграции командной строки API

Список arguments дополнительный, и все аргументы должны следовать синтаксису, подходящему для использования командной строки, как описано в этой секции. Например, специальных символов, которые обработаны системной оболочкой (bash, cmd и т.п.) нужно избежать, и если цитирование необходимо, только цитирование родительской оболочки нужно рассмотреть. Другими словами, если foo bar используется в качестве параметра в bash , кавычки убраны, и экранировка обработана.

Есть два типа аргументов, которые могут использоваться в списке аргументов: позиционные параметры и параметры, передаваемые по имени. Позиционные параметры, например, простые типы, такие как последовательности, числа, булевы, пустые. Параметры, передаваемые по имени, это пары значения ключа, где значения это простые типы. Их использование должно придерживаться следующего образца:

[ positional_argument ]* [ { named_argument* } ]* [ named_argument ]*

Правила для использования этого синтаксиса:

Эти аргументы тогда преобразовываются в аргументы, переданные к вызову метода следующим образом:

Примеры API-интерфейса

Используя интеграцию API, запрос команд MySQL Shell легче, чем с опцией --execute. Следующие примеры показывают, как использовать эту функциональность: