В конце входного json файла были обнаружены лишние символы

Обновлено: 04.07.2024

ClickHouse может принимать ( INSERT ) и отдавать ( SELECT ) данные в различных форматах.

Поддерживаемые форматы и возможность использовать их в запросах INSERT и SELECT перечислены в таблице ниже.

Формат INSERT SELECT
TabSeparated
TabSeparatedRaw
TabSeparatedWithNames
TabSeparatedWithNamesAndTypes
Template
TemplateIgnoreSpaces
CSV
CSVWithNames
CustomSeparated
Values
Vertical
JSON
JSONAsString
JSONStrings
JSONCompact
JSONCompactStrings
JSONEachRow
JSONEachRowWithProgress
JSONStringsEachRow
JSONStringsEachRowWithProgress
JSONCompactEachRow
JSONCompactEachRowWithNamesAndTypes
JSONCompactStringsEachRow
JSONCompactStringsEachRowWithNamesAndTypes
TSKV
Pretty
PrettyCompact
PrettyCompactMonoBlock
PrettyNoEscapes
PrettySpace
Protobuf
ProtobufSingle
Avro
AvroConfluent
Parquet
Arrow
ArrowStream
ORC
RowBinary
RowBinaryWithNamesAndTypes
Native
Null
XML
CapnProto
LineAsString
Regexp
RawBLOB
MsgPack

Вы можете регулировать некоторые параметры работы с форматами с помощью настроек ClickHouse. За дополнительной информацией обращайтесь к разделу Настройки.

TabSeparated

В TabSeparated формате данные пишутся по строкам. Каждая строчка содержит значения, разделённые табами. После каждого значения идёт таб, кроме последнего значения в строке, после которого идёт перевод строки. Везде подразумеваются исключительно unix-переводы строк. Последняя строка также обязана содержать перевод строки на конце. Значения пишутся в текстовом виде, без обрамляющих кавычек, с экранированием служебных символов.

Этот формат также доступен под именем TSV .

Формат TabSeparated поддерживает вывод тотальных значений (при использовании WITH TOTALS) и экстремальных значений (при настройке extremes выставленной в 1). В этих случаях, после основных данных выводятся тотальные значения, и экстремальные значения. Основной результат, тотальные значения и экстремальные значения, отделяются друг от друга пустой строкой. Пример:

Форматирование данных

Числа с плавающей запятой пишутся в десятичной форме. При этом, десятичный разделитель - точка. Поддерживается экспоненциальная запись, а также inf, +inf, -inf, nan. Запись числа с плавающей запятой может начинаться или заканчиваться на десятичную точку.
При форматировании возможна потеря точности чисел с плавающей запятой.
При парсинге, допустимо чтение не обязательно наиболее близкого к десятичной записи машинно-представимого числа.

В качестве исключения, поддерживается также парсинг даты-с-временем в формате unix timestamp, если он состоит ровно из 10 десятичных цифр. Результат не зависит от часового пояса. Различение форматов YYYY-MM-DD hh:mm:ss и NNNNNNNNNN делается автоматически.

Строки выводятся с экранированием спецсимволов с помощью обратного слеша. При выводе, используются следующие escape-последовательности: \b , \f , \r , \n , \t , \0 , \' , \\ . Парсер также поддерживает последовательности \a , \v , и \xHH (последовательности hex escape) и любые последовательности вида \c , где c — любой символ (такие последовательности преобразуются в c ). Таким образом, при чтении поддерживаются форматы, где перевод строки может быть записан как \n и как \ и перевод строки. Например, строка Hello world , где между словами вместо пробела стоит перевод строки, может быть считана в любом из следующих вариантов:

Второй вариант поддерживается, так как его использует MySQL при записи tab-separated дампа.

Минимальный набор символов, которых вам необходимо экранировать при передаче в TabSeparated формате: таб, перевод строки (LF) и обратный слеш.

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

Массивы форматируются в виде списка значений через запятую в квадратных скобках. Элементы массива - числа форматируются как обычно, а даты, даты-с-временем и строки - в одинарных кавычках с такими же правилами экранирования, как указано выше.

NULL форматируется как \N .

Каждый элемент структуры типа Nested представляется как отдельный массив.

TabSeparatedRaw

Отличается от формата TabSeparated тем, что строки выводятся без экранирования.
Используя этот формат, следите, чтобы в полях не было символов табуляции или разрыва строки.

Этот формат также доступен под именем TSVRaw .

TabSeparatedWithNames

Отличается от формата TabSeparated тем, что в первой строке пишутся имена столбцов.

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

Этот формат также доступен под именем TSVWithNames .

TabSeparatedWithNamesAndTypes

Отличается от формата TabSeparated тем, что в первой строке пишутся имена столбцов, а во второй - типы столбцов.
При парсинге, первая и вторая строка полностью игнорируется.

Этот формат также доступен под именем TSVWithNamesAndTypes .

Template

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

Для этого используются настройки format_template_resultset , format_template_row , format_template_rows_between_delimiter и настройки экранирования других форматов (например, output_format_json_quote_64bit_integers при экранировании как в JSON , см. далее)

Настройка format_template_row задаёт путь к файлу, содержащему форматную строку для строк таблицы, которая должна иметь вид:

Настройка format_template_rows_between_delimiter задаёт разделитель между строками, который выводится (или ожмдается при вводе) после каждой строки, кроме последней. По умолчанию \n .

Настройка format_template_resultset задаёт путь к файлу, содержащему форматную строку для результата. Форматная строка для результата имеет синтаксис аналогичный форматной строке для строк таблицы и позволяет указать префикс, суффикс и способ вывода дополнительной информации. Вместо имён столбцов в ней указываются следующие имена подстановок:

  • data - строки с данными в формате format_template_row , разделённые format_template_rows_between_delimiter . Эта подстановка должна быть первой подстановкой в форматной строке.
  • totals - строка с тотальными значениями в формате format_template_row (при использовании WITH TOTALS)
  • min - строка с минимальными значениями в формате format_template_row (при настройке extremes, выставленной в 1)
  • max - строка с максимальными значениями в формате format_template_row (при настройке extremes, выставленной в 1)
  • rows - общее количество выведенных стрчек
  • rows_before_limit - не менее скольких строчек получилось бы, если бы не было LIMIT-а. Выводится только если запрос содержит LIMIT. В случае, если запрос содержит GROUP BY, rows_before_limit - точное число строк, которое получилось бы, если бы не было LIMIT-а.
  • time - время выполнения запроса в секундах
  • rows_read - сколько строк было прочитано при выполнении запроса
  • bytes_read - сколько байт (несжатых) было прочитано при выполнении запроса

У подстановок data , totals , min и max не должны быть указаны типы экранирования (или должен быть указан None ). Остальные подстановки - это отдельные значения, для них может быть указан любой тип экранирования.
Если строка format_template_resultset пустая, то по-умолчанию используется $ .
Из всех перечисленных подстановок форматная строка format_template_resultset для ввода может содержать только data .
Также при вводе формат поддерживает пропуск значений столбцов и пропуск значений в префиксе и суффиксе (см. пример).

Строка JSON должна быть заключена в двойные кавычки, согласно спецификациям , поэтому вам не нужно экранировать '
. Если вам нужно использовать специальный символ в строке JSON, вы можете избежать его, используя символ \ .

См. этот список специальных символов, используемых в JSON:

Однако, даже если это полностью противоречит спецификации, автор может использовать \' .

Это плохо , потому что:

  • Это противоречит спецификации
  • Это больше не допустимая строка JSON

Но это работает, как вы хотите этого или нет.

Для новых читателей всегда используйте двойные кавычки для строк json.

Я потрясен наличием дезинформации с высоким голосом по такому часто обсуждаемому вопросу по основной теме.

Строки JSON нельзя заключать в одинарные кавычки . Различные версии спецификации ( оригинал Дугласа Крокфорда, версия ECMA и версия IETF ) все утверждают, что строки должны быть заключены в двойные кавычки. Это не теоретический вопрос и не вопрос мнения, как это принято в настоящее время; любой анализатор JSON в реальном мире выдаст ошибку, если вы попытаетесь проанализировать строку в одинарных кавычках.

Версия Крокфорда и ECMA даже отображает определение строки, используя красивую картинку, которая должна четко и ясно прояснить ситуацию:

На красивой картинке также перечислены все допустимые escape-последовательности в строке JSON:

    \" литий> \\ литий> \/ литий> \b литий> \f литий> \n литий> \r литий> \t литий>
  • \u , за которым следуют четыре шестнадцатеричные цифры

Обратите внимание, что вопреки бессмыслице в некоторых других ответах здесь, \' никогда не является допустимой escape-последовательностью в строке JSON. Так не должно быть, потому что строки JSON всегда заключаются в двойные кавычки.

Наконец, вам обычно не нужно думать о экранировании символов самостоятельно при программном создании JSON (хотя, конечно, вы будете это делать при ручном редактировании, скажем, файла конфигурации на основе JSON). Вместо этого сформируйте структуру данных, которую вы хотите кодировать, используя любые типы карт, массивов, строк, чисел, логических и нулевых значений, которые есть у вашего языка, а затем закодируйте ее в JSON с помощью функции кодирования JSON. Такая функция, вероятно, встроена в любой используемый вами язык, например, в JavaScript. JSON.stringify , PHP json_encode или json.dumps . Если вы используете язык, который не имеет такой встроенной функциональности, вы можете найти библиотеку синтаксического анализа и кодирования JSON для использования. Если вы просто используете язык или библиотечные функции для преобразования вещей в JSON и обратно, вам даже не нужно знать правила экранирования JSON. Это то, что должен был сделать неверный задающий вопрос.

Все говорят о том, как избежать ' в ' строковый литерал в кавычках. Здесь есть гораздо более серьезная проблема: строковые литералы в одинарных кавычках недопустимы в формате JSON . JSON основан на JavaScript, но это не одно и то же. Если вы пишете литерал объекта внутри кода JavaScript, хорошо; если вам действительно нужен JSON, вам нужно использовать " .

С помощью строк в двойных кавычках вам не нужно экранировать ' . (И если вы хотите, чтобы в строке был буквальный " , вы бы использовали \" )

Может быть, я слишком опоздал на вечеринку, но это будет анализировать /избегать одинарной кавычки (не хочу вступать в битву при разборе против побега) ..

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

Замена каждого "на \" НЕ ДОСТАТОЧНА: Пользователь может ввести ввод: \ и синтаксический анализ, опять же, не удается (подумайте почему).

Вместо этого сначала замените каждый \ на \ (двойной обратный слеш). Только после этого заменяйте каждое «на \» (с обратной косой чертой следует «).

Ответ на прямой вопрос:
В целях безопасности замените необходимый символ на \ u + 4-значный-шестнадцатеричное значение

Пример: Если вы хотите избежать апострофа, замените на \ u0027
D'Amico становится D'Amico

экранирование одинарных кавычек действительно только в одинарных кавычках
двойные кавычки действительны только в двойных кавычках json

Здесь приведены ответы на некоторые распространенные вопросы о встроенной поддержке JSON в SQL Server.

Выходные данные FOR JSON и JSON

FOR JSON PATH или FOR JSON AUTO?

Вопрос. Мне нужно создать текстовый результат JSON из простого SQL-запроса для одной таблицы. Выходные данные для FOR JSON PATH и FOR JSON AUTO совпадают. Какой из этих вариантов следует использовать?

Ответ. Используйте FOR JSON PATH. Несмотря на отсутствие различий в выходных данных JSON, режим AUTO применяет дополнительную логику, определяющую потребность во вложенных столбцах. Рассматривайте PATH как параметр по умолчанию.

Создание вложенной структуры JSON

Вопрос. Мне нужно создать сложную JSON с несколькими массивами на одном уровне. FOR JSON PATH может создавать вложенные объекты с использованием путей, а FOR JSON AUTO создает дополнительный уровень вложенности для каждой таблицы. Ни один из этих параметров не позволяет мне получить нужный результат. Как создать настраиваемый формат JSON, который напрямую не поддерживается существующими параметрами?

Ответ. Любую структуру данных можно создать, добавив запросы FOR JSON в качестве выражений столбца, возвращающих текст JSON. Кроме того, JSON можно создать вручную с помощью функции JSON_QUERY. Применение этих функции показано в приведенном ниже примере.

Каждый результат запроса FOR JSON или функции JSON_QUERY в выражениях столбца форматируется в виде отдельного вложенного подчиненного объекта JSON и включается в основной результат.

Предотвращение появления дважды экранированного JSON в выходных данных FOR JSON

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

Этот запрос получает следующие выходные данные.

Как можно избежать этого? Я хочу, чтобы возвращался в виде объекта JSON, а не escape-текста.

Ответ. JSON, хранящийся в столбце текста или литерале, обрабатывается как обычный текст. В связи с этим он заключается в двойные кавычки и экранируется. Если вам нужно возвратить неэкранированный объект JSON, следует передать столбец JSON как аргумент функции JSON_QUERY, как показано в следующем примере.

JSON_QUERY без второго необязательного параметра возвращает в качестве результата только первый аргумент. Так как JSON_QUERY всегда возвращает правильный объект JSON, FOR JSON определяет, что экранировать этот результат не нужно.

JSON, созданная с помощью предложения WITHOUT_ARRAY_WRAPPER, экранируется в выходных данных FOR JSON

Вопрос. Я пытаюсь отформатировать выражение столбца с помощью FOR JSON и параметра WITHOUT_ARRAY_WRAPPER.

Похоже, что текст, возвращаемый запросом FOR JSON, экранируется как обычный текст. Это происходит только в том случае, если указан WITHOUT_ARRAY_WRAPPER. Почему он не рассматривается в качестве объекта JSON и не включается в результат неэкранированным?

Ответ. Если параметр WITHOUT_ARRAY_WRAPPER указан во внутреннем FOR JSON , создаваемый текст JSON может оказаться недопустимым объектом JSON. Поэтому внешний FOR JSON предполагает, что это обычный текст, и экранирует строку. Если вы уверены, что выходные данные JSON допустимы, заключите их в оболочку с помощью функции JSON_QUERY , чтобы превратить в правильно отформатированную JSON, как показано в следующем примере.

Возвращение вложенного подчиненного объекта JSON из текста JSON с помощью OPENJSON

Вопрос. Не удается открыть массив cоставных объектов JSON, содержащий скалярные значения, объекты и массивы, с помощью OPENJSON с явной схемой. Когда я ссылаюсь на ключ в предложении WITH, возвращаются только скалярные значения. Объекты и массивы возвращаются в виде значений NULL. Как извлекать объекты или массивы в качестве объектов JSON?

Ответ. Если требуется возвратить объект или массив в виде столбца, используйте параметр AS JSON в определении столбца, как показано в следующем примере.

Вместо JSON_VALUE возвращается длинное текстовое значение с параметром OPENJSON.

Вопрос. В тексте JSON имеется ключ описания, содержащий длинный текст. JSON_VALUE(@json, '$.description') возвращает NULL, а не значение.

Ответ. JSON_VALUE предназначена для возврата небольших скалярных значений. Обычно эта функция возвращает значение NULL вместо ошибки переполнения. Если требуется возвратить более длинные значения, используйте OPENJSON, поддерживающую значения NVARCHAR(MAX), как показано в следующем примере.

Для обработки повторяющихся ключей вместо JSON_VALUE используйте параметр OPENJSON.

Вопрос. В тексте JSON есть повторяющиеся ключи. JSON_VALUE возвращает только первый ключ, найденный в пути. Как возвратить все ключи с одинаковыми именами?

Ответ. Встроенные скалярные функции JSON возвращают только первое вхождение объекта, на который указывает ссылка. Если требуется получить несколько ключей, используйте функцию с табличным значением OPENJSON, как показано в следующем примере.

OPENJSON необходим уровень совместимости 130

Вопрос. Я пытаюсь выполнить OPENJSON в SQL Server 2016, но получаю следующую ошибку.

Msg 208, Level 16, State 1 'Invalid object name OPENJSON'

Ответ. Функция OPENJSON доступна только при уровне совместимости 130. Если уровень совместимости базы данных ниже 130, функция OPENJSON будет скрыта. Другие функции JSON доступны на всех уровнях совместимости.

Другие вопросы

Ключи ссылки, содержащие символы, отличные от буквенно-цифровых, в тексте JSON

Вопрос. Ключи в тексте JSON содержат символы, отличные от буквенно-цифровых. Как можно сослаться на эти свойства?

Ответ. Необходимо заключить их в кавычки в путях JSON. Например, JSON_VALUE(@json, '$."$info"."First Name".value') .

Дополнительные сведения о JSON в SQL Server и базе данных SQL Azure

Видео Майкрософт

Наглядные инструкции по встроенной поддержке JSON в SQL Server и базе данных SQL Azure см. в следующих видео.

SQL Server 2016 and JSON Support (SQL Server 2016 и поддержка JSON)

Using JSON in SQL Server 2016 and Azure SQL Database (Использование JSON в SQL Server 2016 и базе данных SQL Azure)

JSON as a bridge between NoSQL and relational worlds (JSON как мост между NoSQL и реляционными решениями)

Я пишу некоторые файлы данных в формате JSON и хотел бы иметь некоторые действительно длинные строковые значения, разделенные на несколько строк. Используя модуль JSON python, я получаю много ошибок, использую ли я \ или \n как escape.

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

ОТВЕТЫ

Ответ 1

JSON не допускает реальных разрывов строк. Вам нужно заменить все разрывы строк на \n .

"first line second line"

можно сохранить с помощью:

"first line\nsecond line"

для Python это должно быть записано как:

"first line\\nsecond line"

где \\ для экранирования обратной косой черты, иначе python будет рассматривать \n как управляющий символ "новая строка"

Ответ 2

Мне пришлось сделать это для небольшого проекта Node.js и нашел это обход:

Это выглядит довольно аккуратно для меня, appart из того, что я должен использовать двойные кавычки повсюду. Хотя в противном случае я мог бы, возможно, использовать YAML, но у этого есть другие подводные камни и не поддерживается изначально. После разбора я просто использую myData.modify_head.join('\n') или myData.modify_head.join() , в зависимости от того, хочу ли я прерывать строку после каждой строки или нет.

Ответ 3

Ознакомьтесь с спецификацией! Произведение грамматики JSON char может принимать следующие значения:

  • любой-Unicode-символов except- " -или- \ -или-контроль символов
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u четыре шестнадцатеричных цифры

Newlines - это "управляющие символы", поэтому нет, у вас может не быть буквальной новой строки внутри вашей строки. Однако вы можете закодировать его, используя любую комбинацию \n и \r , которая вам нужна.

Ответ 4

JSON не позволяет разбивать строки на удобочитаемость.

Лучше всего использовать IDE, которая будет обертываться для вас.

Ответ 5

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

JSON не допускает "настоящие" переводы строк в своих данных; он мог только избежать новых строк. Смотрите ответ от @YOU. В соответствии с вопросом, похоже, что вы пытались избежать разрывов строк в Python двумя способами: с помощью символа продолжения строки ( "\" ) или с помощью "\n" в качестве escape.

Но имейте в виду: если вы используете строку в Python, специальные экранированные символы ( "\t" , "\n" ) переводятся в РЕАЛЬНЫЕ управляющие символы! "\n" будет заменен управляющим символом ASCII, представляющим символ новой строки, который является именно тем символом, который недопустим в JSON. (Что касается символа продолжения строки, он просто выводит новую строку.)

Так что вам нужно сделать так, чтобы Python не экранировал символы. Вы можете сделать это, используя необработанную строку (поместите r перед строкой, как в r"abc\ndef" , или r"abc\ndef" дополнительную косую черту перед новой "abc\\ndef" ( "abc\\ndef" ).

В обоих случаях вместо замены "\n" на реальный управляющий символ ASCII новой строки будет оставлено "\n" как два литеральных символа, которые затем JSON может интерпретировать как экранирование новой строки.

Ответ 6

И хуже всего то, что нет хорошего ответа.

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

Но json не является языком программирования; это просто представление данных. Вы не можете сказать это, чтобы объединить строки. Кроме того, в его (довольно малой) грамматике нет никакого средства для представления строки на нескольких строках.

За исключением разработки какого-либо препроцессора (и я, например, не хочу, чтобы эффективно составлять собственный язык для решения этой проблемы), нет общего решения этой проблемы. ЕСЛИ вы можете изменить формат данных, тогда вы можете заменить массив строк. В противном случае это один из многочисленных способов, с помощью которых json не предназначен для удобочитаемости.

Ответ 7

Возможно ли иметь многострочные строки в JSON?

Да. Я просто протестировал это сейчас со своим веб-браузером Firefox, нажав F12, нажав консоль и набрав в нижней части экрана.

Объект x только что был создан из строки формата JSON, содержащей многострочную строку.

x.text, показывающий, что это многострочная строка.

Эти два теста показывают, что интерпретатор Firefox Javascript с радостью создает и использует JSON с многострочными строками.

Дополнительные тесты с JSON.stringify и JSON.parse показали, что интерпретатор Javascript может преобразовать объект, содержащий многострочные строки в JSON, и проанализировать его снова без каких-либо проблем.

В прошлом я хранил полные работы Шекспира как свойство в объекте JSON, а затем отправлял его через Интернет, без искажений.

Вот две строки, введенные в три строки

Мы можем отобразить объект

Конец строк в строке получается из использования \n и несколько входных линий достигаются с помощью только\в конце строки.

На практике вам может понадобиться синхронизировать концы строк с строками в строке, например

Обратите внимание, что строка с новой строкой не длиннее строки с пробелом. Несмотря на то, что на клавиатуре были введены два символа ('\' и 'n'), в строке сохраняется только один символ.

Ответ 8

Мы всегда можем использовать массив строк для многострочных строк, например:

И мы можем легко перебирать массив для отображения контента в многострочном режиме.

Ответ 9

Используйте regex для замены всех вхождений \r\n на \\n .

Это работало для меня в scala.

Ответ 10

Ответ 11

Если вы хотите использовать Node.js, вы можете сделать это:

Вы можете импортировать с помощью Node.js и легко конвертировать его в JSON, например:

как это работает: вы используете Node.js для загрузки модуля JS, который создает объект JS, который может быть легко преобразован в JSON с помощью Node.js. Опция -e оценивает строку, а опция -p результат возврата последней операции Node.js в стандартный вывод.

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

Ответ 12

Машины не заботятся, люди могут изменить параметры просмотра. Я действительно не мог понять проблему

Ответ 13

для мультилинии я использую:

Ответ 14

Оберните каждую строку в кавычки и завершите их запятой, как показано ниже:

Ответ 15

Ответ 16

вы можете просто запустить код ниже с вашим желанием многострочной строки между тильдой

Ответ 17

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

после кодировки строки base64

Ответ 20

написать любой текст в блокноте ++ с помощью multi multi line затем нажмите ctl + a и ctl + j, чтобы расположить их в одной строке

В файле json напишите:

Ответ 21

поместите многострочный текст в txt файл, а затем

(он работает на mongoDB)

Ответ 22

Вы можете попробовать разместить <div></div> между предложениями.

Читайте также: