sql-metadata icon indicating copy to clipboard operation
sql-metadata copied to clipboard

Can't extract list of all columns with saving the order of them

Open rrr2rrr opened this issue 1 year ago • 1 comments

Query

SELECT 
    dj.field_1,
    cardinality(dj.field_1) as field_1_count,
    dj.field_2,
    cardinality(dj.field_2) as field_2_count,
    dj.field_3 as field_3
FROM dj

Code

parser = Parser(sql_query)
print(parser.columns)
print(parser.columns_aliases)

Output

['dj.field_1', 'dj.field_2', 'dj.field_3']
{'field_1_count': 'dj.field_1', 'field_2_count': 'dj.field_2', 'field_3': 'dj.field_3'}

Feature needed

[
   'field_1': {'refer':'dj.field_1'}, 
   'field_1_count': {'alias':'field_1_count', 'refer':'dj.field_1'},
   'field_2': {'refer':'dj.field_2'}, 
   'field_2_count': {'alias':'field_2_count', 'refer':'dj.field_2'},
   'field_3': {'alias':'field_3', 'refer':'dj.field_3'}
]

rrr2rrr avatar Feb 24 '24 13:02 rrr2rrr

Quick local fix

To fix it in my case I added aliases to all columns:

def add_alias_to_sql_select_fields(sql_query):
    # Splitting the query into parts before and after the FROM clause
    select_part, from_part = sql_query.split("FROM")
    
    # Splitting the SELECT part into fields
    fields = select_part.replace("SELECT", "").strip().split(",")
    
    new_fields = []
    for field in fields:
        field = field.strip()
        # Check if field already has an alias
        if " as " not in field.lower():
            # Extracting the field name after the last dot for alias
            field_name = field.split(".")[-1].strip()
            # Adding alias
            field_with_alias = f"{field} as {field_name}"
        else:
            field_with_alias = field
        new_fields.append(field_with_alias)
    
    # Reconstructing the SELECT part with aliases
    new_select_part = "SELECT\n    " + ",\n    ".join(new_fields)
    
    # Reconstructing the full query
    new_sql_query = f"{new_select_part}\nFROM{from_part}"
    
    return new_sql_query

# Your SQL query
sql_query = """
SELECT 
    dj.field_1,
    cardinality(dj.field_1) as field_1_count,
    dj.field_2,
    cardinality(dj.field_2) as field_2_count,
    dj.field_3
FROM dj
"""

# Adding aliases
new_sql_query = add_alias_to_sql_select_fields(sql_query)
print(new_sql_query)

Output

SELECT
    dj.field_1 as field_1,
    cardinality(dj.field_1) as field_1_count,
    dj.field_2 as field_2,
    cardinality(dj.field_2) as field_2_count,
    dj.field_3 as field_3
FROM dj

rrr2rrr avatar Feb 24 '24 13:02 rrr2rrr