0

現在、ユーザーからの入力に応じてSQLクエリを作成しています。これがどのように行われるかの例はここで見ることができます:

def generate_conditions(table_name,nameValues):
    sql = u""
    for field in nameValues:
        sql += u" AND {0}.{1}='{2}'".format(table_name,field,nameValues[field])
    return sql

search_query = u"SELECT * FROM Enheter e LEFT OUTER JOIN Handelser h ON e.Id == h.Enhet WHERE 1=1"

if "Enhet" in args:
    search_query += generate_conditions("e",args["Enhet"])
c.execute(search_query)

SQLは毎回変更されるため、execute呼び出しに値を挿入できません。つまり、文字列を手動でエスケープする必要があります。しかし、私がすべての人を検索すると、実行するポイントが...

また、クエリの生成方法にも満足していません。そのため、誰かが別の方法について何かアイデアを持っている場合は、それも素晴らしいことです。

4

1 に答える 1

2

2つのオプションがあります。

  1. SQLAlchemyの使用に切り替えます; これにより、動的SQLの生成がよりPythonになり、適切な引用が保証されます。

  2. テーブル名と列名にパラメーターを使用することはできないため、これらをクエリに含めるには、文字列フォーマットを使用する必要があります。一方、データベースがステートメントを準備できる場合に限り、値は常にSQLパラメータを使用する必要があります

    ユーザー入力から直接取得したテーブル名と列名を補間することはお勧めできませんそのように任意のSQLステートメントを挿入するのは非常に簡単です。代わりに受け入れる名前のリストに対して、テーブル名と列名を確認してください。

    だから、あなたの例に基づいて、私はこの方向に進みます:

    tables = {
        'e': ('unit1', 'unit2', ...),   # tablename: tuple of column names
    }
    
    def generate_conditions(table_name, nameValues):
        if table_name not in tables:
            raise ValueError('No such table %r' % table_name)
        sql = u""
        params = []
        for field in nameValues:
            if field not in tables[table_name]:
                raise ValueError('No such column %r' % field)
            sql += u" AND {0}.{1}=?".format(table_name, field)
            params.append(nameValues[field])
        return sql, params
    
    search_query = u"SELECT * FROM Enheter e LEFT OUTER JOIN Handelser h ON e.Id == h.Enhet WHERE 1=1"
    
    search_params = []
    if "Enhet" in args:
        sql, params = generate_conditions("e",args["Enhet"])
        search_query += sql
        search_params.extend(params)
    c.execute(search_query, search_params)
    
于 2012-09-12T13:50:58.973 に答える