Таблица не найдена, потому что get_ddl преобразует имя таблицы в ВЕРХНИЙ РЕГИСТР

#python #sql

#python #sql

Вопрос:

Я пишу скрипт на python, используя snowflake_python_onnector. Цель состоит в том, чтобы извлечь DDLS существующих объектов (например, таблиц, каналов, этапов) из snowflake в файлы .sql на локальном компьютере.

Когда я запускаю скрипт, у меня появляется ошибка только с именами таблиц, которые не указаны в верхнем регистре:

 query: [SELECT GET_DDL('TABLE', 'PNC_GWCC_12651_RW.**cc_BudgetLine**') script]
2020-08-27 10:25:37 INFO     query execution done
2020-08-27 10:25:37 ERROR    002003 (02000): 01968619-0009-26fe-0000-1c2d074c77e6: SQL compilation error:
Table 'INTE_SDP_LZ_PERS.PNC_GWCC_12651_RW.**CC_BUDGETLINE**' does not exist or not authorized.
  

Я поместил код ниже. Как я могу решить проблему?

Приветствую, Ольга

 OBJECT_LIST_QUERY = """
SELECT seq, catalog_name, schema_name, object_type, object_name, ARGUMENT_SIGNATURE, script
FROM (
    select '01' seq, DATABASE_NAME catalog_name, '*' schema_name, 'DATABASE' object_type, DATABASE_NAME object_name, '' ARGUMENT_SIGNATURE
           , 'CREATE OR REPLACE' || CASE WHEN D.IS_TRANSIENT = 'YES' THEN ' TRANSIENT' ELSE '' END || ' ' ||
           'DATABASE ' || D.DATABASE_NAME || ' ' ||
           'nDATA_RETENTION_TIME_IN_DAYS = ' || TO_VARCHAR(RETENTION_TIME) ||
           CASE WHEN D.COMMENT IS NULL THEN '' ELSE 'nCOMMENT = ''' || D.COMMENT || '''' END || ';' script
      from INFORMATION_SCHEMA.DATABASES D
      WHERE DATABASE_NAME = '{}' 
      UNION ALL
    select '02' seq, catalog_name, schema_name schema_name, 'SCHEMA' object_type, schema_name object_name, '' ARGUMENT_SIGNATURE
           , 'CREATE OR REPLACE' || CASE WHEN S.IS_TRANSIENT = 'YES' THEN ' TRANSIENT' ELSE '' END || ' ' ||
           'SCHEMA ' || S.SCHEMA_NAME || ' ' ||
           CASE WHEN S.IS_MANAGED_ACCESS = 'YES' THEN 'nWITH MANAGED ACCESS' ELSE '' END || ' ' ||
           'nDATA_RETENTION_TIME_IN_DAYS = ' || TO_VARCHAR(RETENTION_TIME) ||
           CASE WHEN S.COMMENT IS NULL THEN '' ELSE 'nCOMMENT = ''' || S.COMMENT || '''' END || ';' script
      from INFORMATION_SCHEMA.SCHEMATA S
      UNION ALL
    select '03' seq, table_catalog catalog_name, TABLE_SCHEMA schema_name, 'TABLE' object_type, TABLE_NAME object_name, '' ARGUMENT_SIGNATURE, '' script
      from INFORMATION_SCHEMA.TABLES
      WHERE TABLE_TYPE != 'VIEW'
      UNION ALL
    select '04' seq, table_catalog catalog_name, TABLE_SCHEMA schema_name, 'VIEW' object_type, TABLE_NAME object_name, '' ARGUMENT_SIGNATURE, '' script
      from INFORMATION_SCHEMA.VIEWS 
      WHERE TABLE_SCHEMA != 'INFORMATION_SCHEMA'
      UNION ALL
    select '06' seq, SEQUENCE_catalog catalog_name, SEQUENCE_SCHEMA schema_name, 'SEQUENCE' object_type, SEQUENCE_NAME object_name, '' ARGUMENT_SIGNATURE, '' script
      from INFORMATION_SCHEMA.SEQUENCES
      UNION ALL
    select '07' seq, FILE_FORMAT_catalog catalog_name, FILE_FORMAT_SCHEMA schema_name, 'FILE_FORMAT' object_type, FILE_FORMAT_NAME object_name, '' ARGUMENT_SIGNATURE, '' script
      from INFORMATION_SCHEMA.FILE_FORMATS
      UNION ALL
    select '08' seq, PIPE_catalog catalog_name, PIPE_SCHEMA schema_name, 'PIPE' object_type, PIPE_NAME object_name, '' ARGUMENT_SIGNATURE, '' script
      from INFORMATION_SCHEMA.PIPES 
      UNION ALL
    select '09' seq, FUNCTION_catalog catalog_name, FUNCTION_SCHEMA schema_name, 'FUNCTION' object_type, FUNCTION_NAME object_name, ARGUMENT_SIGNATURE, '' script
      from INFORMATION_SCHEMA.FUNCTIONS 
      UNION ALL
    select '10' seq, PROCEDURE_catalog catalog_name, PROCEDURE_SCHEMA schema_name, 'PROCEDURE' object_type, PROCEDURE_NAME object_name, ARGUMENT_SIGNATURE, '' script
      from "INFORMATION_SCHEMA"."PROCEDURES"
  ) T
ORDER BY seq, catalog_name, schema_name, object_name"""

GET_DDL_QUERY = "SELECT GET_DDL('{}', '{}') script"
  

Комментарии:

1. Вы упомянули, что используете Snwflake DB. Если это правильно, ваша интерпретация того, почему это неправильно, неверна, потому что идентификаторы не чувствительны к регистру. SELECT * FROM PNC_GWCC_12651_RW.cc_BudgetLine будет работать так же, как SELECT * FROM PNC_GWCC_12651_RW.CC_BUDGETLINE

2. CC_BUDGETLINE это представление или таблица? найдено ли оно в INTE_SDP_LZ_PERS базе данных, в PNC_GWCC_12651_RW схеме?

3. Привет @GabrielDurac: PNC_GWCC_12651_RW.cc_BudgetLine — это таблица. ВЫБЕРИТЕ * Из PNC_GWCC_12651_RW.CC_BUDGETLINE не работает, потому что это таблица с учетом регистра cc_BudgetLine.

4. INTE_SDP_LZ_PERS — это база данных, PNC_GWCC_12651_RW — это схема

5. Попробуйте использовать двойные кавычки вокруг имени таблицы. ВЫБЕРИТЕ GET_DDL(‘ТАБЛИЦА’, ‘PNC_GWCC_12651_RW.»cc_BudgetLine»‘ )

Ответ №1:

По умолчанию Snowflake применяет следующие правила для хранения идентификаторов (во время создания / определения) и их разрешения (в запросах и других операторах SQL):

  • Когда идентификатор не заключен в кавычки, он сохраняется и разрешается в верхнем регистре.
  • Когда идентификатор заключен в двойные кавычки, он сохраняется и разрешается точно так, как введен, включая регистр.

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

 SELECT GET_DDL('TABLE', 'PNC_GWCC_12651_RW."cc_BudgetLine"' )