[Redash] Redshift에서 임시 테이블을 사용하는 경우 스키마 정보를 검색하지 못할 수 있음

5805 단어 redash7redash

운영 환경


  • Redash on Docker
  • Redash version: redash/redash:7.0.0.b18042

  • 현상



    Redshift를 데이터 소스에 등록한 후 쿼리를 작성(또는 편집)하는 대시보드에서 원래 왼쪽 창에 표시되어야 하는 스키마 정보가 표시되지 않고 페이지 오른쪽 하단에 다음 오류 메시지가 표시됨 있습니다.
    ※ 물론 아무리 기다려도 스키마는 표시되지 않습니다.



    원인 조사



    Redash Scheduler 로그를 확인할 때 다음 예외 오류가 발생했습니다.
    6d6321902c Failed refreshing schema for the data source: DS_Redshift
    Traceback (most recent call last):
      File "/app/redash/tasks/queries.py", line 238, in refresh_schema
        ds.get_schema(refresh=True)
      File "/app/redash/models/__init__.py", line 157, in get_schema
        schema = sorted(query_runner.get_schema(get_stats=refresh), key=lambda t: t['name'])
      File "/app/redash/query_runner/__init__.py", line 134, in get_schema
        self._get_tables(schema_dict)
      File "/app/redash/query_runner/pg.py", line 289, in _get_tables
        self._get_definitions(schema, query)
      File "/app/redash/query_runner/pg.py", line 113, in _get_definitions
        raise Exception("Failed getting schema.")
    Exception: Failed getting schema.
    

    분명히 스키마 정보를 얻는 스크립트 /app/redash/query_runner/pg.py에 문제가있는 것 같습니다.

    그래서 /app/redash/query_runner/pg.py의 113 행 주변을 확인하면,

    /app/redash/query_runner/pg.py(109-113행 주변)
        def _get_definitions(self, schema, query):
            results, error = self.run_query(query, None)
    
            if error is not None:
                raise Exception("Failed getting schema.")
    

    단지 인수로 지정된 쿼리를 실행하고 있습니다. 한층 더 이 메소드를 호출하고 있는 개소를 중심으로 조사해 보면, 다음의 쿼리를 건네주고 있는 것을 알았습니다.

    /app/redash/query_runner/pg.py(269-287행 주변)
            query = """
            WITH tables AS (
                SELECT DISTINCT table_name,
                                table_schema,
                                column_name,
                                ordinal_position AS pos
                FROM svv_columns
                WHERE table_schema NOT IN ('pg_internal','pg_catalog','information_schema')
            )
            SELECT table_name, table_schema, column_name
            FROM tables
            WHERE
                HAS_SCHEMA_PRIVILEGE(table_schema, 'USAGE') AND
                (
                    table_schema IN (SELECT schemaname FROM SVV_EXTERNAL_SCHEMAS) OR
                    HAS_TABLE_PRIVILEGE('"' || table_schema || '"."' || table_name || '"', 'SELECT')
                )
            ORDER BY table_name, pos
            """
    

    수동으로 위의 쿼리를 Redshift에 던지면 다음 오류가 발생했습니다.
    ERROR:  schema "pg_temp_25" does not exist
    

    참고로 pg_temp_25는 타이밍에 따라 pg_temp_8이거나 pg_temp_10이지만, 요컨대 pg_temp로 시작하는 이름의 스키마를 찾을 수없는 경우가 있습니다.

    사실 이 pg_temp 로 시작하는 스키마는 CREATE TEMPORARY TABLE 로 임시 테이블을 작성했을 때, 동시에 작성되는 것 같습니다.
    Redshift 의 사양에서는, 임시 테이블은 세션이 끊어졌을 때에 자동으로 삭제되는 것 같습니다만, 임시 스키마는 자동으로 삭제되지 않고, 또한 수동으로 삭제하는 수술이 준비되어 있지 않은 것 같습니다. (참고: htps : // 코 m / 썩은 s 쓰레기 / ms / 6 2b4103758 7287bc)

    또한 우리 회사는 Tableau에서 Redshift를 사용했으며 그곳에서 만든 임시 테이블과 임시 스키마가 많이있었습니다.

    대책



    원래 임시 테이블이나 임시 스키마를 Redash에서 사용할 필요가 없으므로 스키마 검색 쿼리를 pg_temp로 시작하는 임시 스키마를 제외하도록 변경합니다.

    이번에는 다음과 같은 Patch, Dockerfile을 만들고 다시 빌드하여 대응했습니다.

    pg.py.patch
    --- pg.py.org   2019-10-29 17:21:07.837000000 +0900
    +++ pg.py   2019-10-29 17:21:41.357782805 +0900
    @@ -274,6 +274,7 @@
                                 ordinal_position AS pos
                 FROM svv_columns
                 WHERE table_schema NOT IN ('pg_internal','pg_catalog','information_schema')
    +              AND table_schema NOT LIKE 'pg_temp_%'
             )
             SELECT table_name, table_schema, column_name
             FROM tables
    

    Dockerfile
    FROM redash/redash:7.0.0.b18042
    
    ADD pg.py.patch /tmp/pg.py.patch
    
    RUN patch -u /app/redash/query_runner/pg.py </tmp/pg.py.patch && \
        rm -f /tmp/pg.py.patch
    

    좋은 웹페이지 즐겨찾기