如何把字典转换成SQL Query?

How to convert dictionary into SQL Query?

提问人:Nason Thomas 提问时间:10/22/2023 最后编辑:toyota SupraNason Thomas 更新时间:10/23/2023 访问量:97

问:

我需要将我的python字典转换为sql查询。下面是我的字典的样子

dict_info = {
    "Tables": [
        "product",
        "sales"
    ],
    "Columns": {
        "product": [
            "prod_id",
            "prod_desc",
        ],
        "sales": [
            "prod_id",
            "prod_sales",
            "prod_qty"
        ]
    },
    "Filter": {
        "region_id": "1,2",
        "state_id": "4,7,9",
        "store_id": "14",
    }
}

我正在尝试进行两个不同的查询,因为有两个表信息。(如果是 3 个表,那么我必须进行 3 个不同的查询。

我需要什么。

Query1= " SELECT product.prod_id, product.prod_desc FROM product WHERE product.region_id in 
          (1,2) AND product.state_id in (4,7,9) AND product.store_id in (14);

Query2= " SELECT product.prod_id, product.prod_sales, product.prod_qty FROM product WHERE
          sales.region_id in (1,2) AND sales.state_id in (4,7,9) AND sales.store_id in (14);

我尝试过:

import pandas as pd
import numpy as np

get_tables = dict_info.get("Tables", [])
get_columns = dict_info.get("Columns", [])

for i in tables:
    query = "SELECT " + ", ".join(columns[i]) + ' FROM ' + i ";"

需要有关如何将筛选语句放入同一查询中并为每个所选表创建动态查询的帮助。

python sql pandas 字典

评论

1赞 RomanPerekhrest 10/22/2023
使用可以使它更容易sqlalchemy
0赞 Mark 10/22/2023
使用库也更安全。尽管这并不难做到,但如果不知道这是如何使用的,我会犹豫不决,因为在许多情况下,使用字符串插值来制作 SQL 是一种危险的做法。
0赞 Nason Thomas 10/22/2023
嘿@Mark,用例是,当人们点击我的 API 时,我会得到这个带有正文的字典,基于我需要将 dict 转换为 sql query 的字典,以便我可以在数据库中运行 sql 查询并获取结果并返回相同的结果。但是字典可以包含任何内容,例如 agg、join 等......试图为此创建动态解决方案。欢迎任何建议
0赞 snakecharmerb 10/22/2023
你最好找到一个现有的查询构建包来做到这一点(pypika 看起来很有前途,尽管我没有使用过它)。尝试使用字符串连接来执行此操作是 SQL 注入的高风险。试图制作一些能够涵盖所有可能性的东西是一项非常广泛的任务。
1赞 Mark 10/23/2023
如果这个字典来自 api 用户,这种方法是危险的。公认的解决方案使某人删除您的所有数据变得微不足道。你绝对不应该这样做。

答:

2赞 Nathan Chbret 10/22/2023 #1

为此,可以循环访问字典中的表和列,并在每个查询的末尾附加筛选条件:

def generate_sql_queries(dict_info):
    queries = []
    
    # Extracting filter conditions + formating them
    filters = dict_info.get("Filter", {})
    filter_conditions = []
    for column, values in filters.items():
        values = values.split(',')
        condition = f"{column} in ({','.join(values)})"
        filter_conditions.append(condition)
    filter_str = " AND ".join(filter_conditions)
    
    # Generating queries for tables
    tables = dict_info.get("Tables", [])
    columns_dict = dict_info.get("Columns", {})
    for table in tables:
        columns = columns_dict.get(table, [])
        columns_str = ', '.join([f"{table}.{col}" for col in columns])
        query = f"SELECT {columns_str} FROM {table} WHERE {filter_str};"
        queries.append(query)
    
    return queries

# Example use:
dict_info = {
    # your dictionary is here
}

queries = generate_sql_queries(dict_info)
for i, query in enumerate(queries, 1):
    print(f"Query{i} = \"{query}\"")
3赞 Tusher 10/22/2023 #2

我尝试了这种方式来解决您的问题:

dict_info = {
    "Tables": ["Table1", "Table2"],
    "Columns": {
        "Table1": ["Column1", "Column2"],
        "Table2": ["Column3", "Column4"],
    },
    "Filter": {
        "Table1": {"Key1": [1, 2, 3], "Key2": [4, 5]},
        "Table2": {"Key3": [6, 7, 8]}
    }
}

tables = dict_info.get("Tables", [])
columns = dict_info.get("Columns", {})
filters = dict_info.get("Filter", {})

for table in tables:
    cols = ", ".join([f"{table}.{col}" for col in columns.get(table, [])])
    
    # Construct the WHERE clause for the current table
    filter_items = filters.get(table, {})
    where_clauses = []
    for key, values in filter_items.items():
        if values:  # Check if the list of values is not empty
            values_str = ', '.join(map(str, values))
            where_clauses.append(f"{table}.{key} IN ({values_str})")
    
    where = " AND ".join(where_clauses)
    
    query = f"SELECT {cols} FROM {table}"
    if where:
        query += f" WHERE {where};"
    else:
        query += ";"
    
    print(query)

在这里,我使用测试来确保空列表或缺少键不会导致问题。为了解决某个表可能缺少列或筛选器的情况,列和构造代码已更改。

你的输出看起来像:

SELECT Table1.Column1, Table1.Column2 FROM Table1 WHERE Table1.Key1 IN (1, 2, 3) AND Table1.Key2 IN (4, 5);
SELECT Table2.Column3, Table2.Column4 FROM Table2 WHERE Table2.Key3 IN (6, 7, 8);