sql. Идентификатор без кавычек - PullRequest
1 голос
/ 28 января 2020

Я выполнил поиск в Интернете по запросу "sql .Identifier без кавычек", и этот пост был актуален только. Советует использовать .format(sql.Identifier.

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

Я не вижу опции в sql.Identifier, чтобы пропустить цитирование в документе и альтернативные методы в sql модуле psycopg2. Как я могу использовать PostgreSQL из Python безопасным для инъекций способом для идентификаторов без кавычек?

ДОБАВЛЕНО: моя путаница возникла из-за того, что я использовал "publi c .ab c" для sql .Identifier, когда, как отмечено в ответе @klin, мне следовало использовать два идентификатора. После этого я вижу, что кавычки используются только для чувствительных к регистру (и / или где используются «другие» символы, такие как точка).

Ответы [ 3 ]

1 голос
/ 28 января 2020

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

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

Именно при сложении регистра можно получить странные результаты: когда вы пишете create table Foo () или select Foo from Bar, Postgres сначала применяет свои правила сворачивания регистра к идентификаторам без кавычек, а затем делает все остальное. Таким образом, если вы заключаете в кавычки идентификаторы, вам нужно соответствовать результат этого сгиба:

  • postgres сворачивается в нижний регистр (это явно задокументировано), при условии, что вы строчные идентификаторы в кавычках, они будут совпадать с идентификаторами без кавычек, однако это не заключенные в кавычки записи
  • однако это не переносимо, потому что SQL spe c требует прописные буквы сворачивание
  • и поскольку в базах данных выполняется смещение регистра, а не сопоставление без учета регистра, термины, созданные с использованием идентификаторов в кавычках, могут быть вообще недоступны из идентификаторов без кавычек, например, если вы создадите таблицу "Foo", select from Foo даже не будет увидеть это :
# create table "Foo" ();
CREATE TABLE
# select from "Foo";
--
(0 rows)

# select from Foo;
ERROR:  relation "foo" does not exist
LINE 1: select from Foo;
                    ^
1 голос
/ 28 января 2020

Вы должны различать guish между двумя разными ситуациями. Если вы хотите использовать заглавные буквы в чувствительных к регистру идентификаторах, вы должны использовать двойные кавычки. Если вы используете только строчные буквы для идентификаторов, вы можете , но вам не нужно использовать двойные кавычки. Эксперты обычно рекомендуют избегать первого случая. Во втором случае кавычки, автоматически добавляемые psycopg2, не являются проблемой.

Обратите внимание, что public.abc - это , а не идентификатор, это выражение, содержащее два идентификатора. Следовательно, вы должны использовать его следующим образом:

sql.SQL("select * from {}.{}").format(sql.Identifier(schema_name), sql.Identifier(table_name))

или это:

sql.SQL("select * from {}").format(sql.Identifier(schema_name, table_name))

как (согласно документации ):

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

1 голос
/ 28 января 2020

Если ваш API базы данных регулярно заключает в кавычки идентификаторы, это хорошая вещь . Не пытайтесь обойти это.

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

Цитирование идентификатора, который не требует цитирования, является безвредным, и на самом деле это хорошая мера безопасности.

...