getredash/redash · error · CreateTableError

Error creating table {}: {}

Error message

Error creating table {}: {}

What it means

Raised by create_table (redash/query_runner/query_results.py:132) as CreateTableError when connection.execute of the generated 'CREATE TABLE ...' statement raises sqlite3.OperationalError. The message embeds the table name and the sqlite error text, which names the actual cause (duplicate table, illegal identifier, etc.). This code backs the query_results loader that materializes other queries' results into a temp SQLite database.

Source

Thrown at redash/query_runner/query_results.py:132

    elif isinstance(value, datetime.timedelta):
        return str(value)
    else:
        return value


def create_table(connection, table_name, query_results):
    try:
        columns = [column["name"] for column in query_results["columns"]]
        safe_columns = [fix_column_name(column) for column in columns]

        column_list = ", ".join(safe_columns)
        create_table = "CREATE TABLE {table_name} ({column_list})".format(
            table_name=table_name, column_list=column_list
        )
        logger.debug("CREATE TABLE query: %s", create_table)
        connection.execute(create_table)
    except sqlite3.OperationalError as exc:
        raise CreateTableError("Error creating table {}: {}".format(table_name, str(exc)))

    insert_template = "insert into {table_name} ({column_list}) values ({place_holders})".format(
        table_name=table_name,
        column_list=column_list,
        place_holders=",".join(["?"] * len(columns)),
    )

    for row in query_results["rows"]:
        values = [flatten(row.get(column)) for column in columns]
        connection.execute(insert_template, values)


def prepare_parameterized_query(query, query_params):
    for params in query_params:
        table_hash = hashlib.md5(
            "query_{query}_{hash}".format(query=params[0], hash=params[1]).encode(), usedforsecurity=False
        ).hexdigest()
        key = "param_query_{query_id}_{{{param_string}}}".format(query_id=params[0], param_string=params[1])

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Read the embedded sqlite error text — 'table X already exists' means DROP TABLE IF EXISTS first or use a fresh temp name
  2. Sanitize/quote column names before create_table (replace '"' and unusual characters)
  3. For loader queries, ensure each run uses a new in-memory SQLite connection or drops previously created tables

Example fix

# before
create_table(connection, table_name, columns)
# after
connection.execute('DROP TABLE IF EXISTS {}'.format(table_name))
create_table(connection, table_name, columns)
Defensive patterns

Strategy: try-catch

Validate before calling

existing = connection.execute("select name from sqlite_master where type='table' and name=?", (table_name,)).fetchone()
if existing:
    connection.execute('DROP TABLE IF EXISTS {}'.format(table_name))

Try / catch

try:
    create_table(connection, table_name, columns)
except CreateTableError as e:
    logger.error('create_table failed: %s', e)
    connection.execute('DROP TABLE IF EXISTS {}'.format(table_name))
    create_table(connection, table_name, columns)

Prevention

When it happens

Trigger: Calling create_tables_from_query_ids / create_table twice for the same table name (table already exists), or with column names containing characters SQLite rejects unquoted (e.g. mismatched quoting when double quotes or colons are involved), or when the column list is empty producing invalid SQL.

Common situations: Rerunning a results-loader query against a persistent connection where the temp table was not dropped; upstream result sets whose column names contain quotes/colons that break identifier quoting; schema drift producing columns the quoting logic mishandles.

Related errors


AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28). Data as JSON: /api/errors/4e074d3bc7493288. Report an issue: GitHub.