17

HTML ファイルから挿入ステートメント (postgresql 用) のリストを生成する必要があります。名前/値を適切にエスケープして引用するのに役立つ Python 用のライブラリはありますか? PHP では、PDO を使用してエスケープと引用を行います。Python に相当するライブラリはありますか?

編集:後で実行するために、SQLステートメントを含むファイルを生成する必要があります

4

5 に答える 5

26

これは古い質問であることは知っていますが、OPが望んでいるように見えるもの、つまり基本的なSQLを生成するための非常に単純なライブラリが欲しかったことがよくあります。

以下の関数はまさにそれを行います。使用するデータを含むテーブル名と辞書を指定すると、必要な操作の SQL クエリが返されます。

キーと値のペアは、データベース行のフィールド名と値を表します。

def read(table, **kwargs):
    """ Generates SQL for a SELECT statement matching the kwargs passed. """
    sql = list()
    sql.append("SELECT * FROM %s " % table)
    if kwargs:
        sql.append("WHERE " + " AND ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems()))
    sql.append(";")
    return "".join(sql)


def upsert(table, **kwargs):
    """ update/insert rows into objects table (update if the row already exists)
        given the key-value pairs in kwargs """
    keys = ["%s" % k for k in kwargs]
    values = ["'%s'" % v for v in kwargs.values()]
    sql = list()
    sql.append("INSERT INTO %s (" % table)
    sql.append(", ".join(keys))
    sql.append(") VALUES (")
    sql.append(", ".join(values))
    sql.append(") ON DUPLICATE KEY UPDATE ")
    sql.append(", ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems()))
    sql.append(";")
    return "".join(sql)


def delete(table, **kwargs):
    """ deletes rows from table where **kwargs match """
    sql = list()
    sql.append("DELETE FROM %s " % table)
    sql.append("WHERE " + " AND ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems()))
    sql.append(";")
    return "".join(sql)

あなたはそれをそのように使います。テーブル名と辞書を指定するだけです (または Python の **kwargs 機能を使用します):

>>> upsert("tbl", LogID=500, LoggedValue=5)
"INSERT INTO tbl (LogID, LoggedValue) VALUES ('500', '5') ON DUPLICATE KEY UPDATE LogID = '500', LoggedValue = '5';"

>>> read("tbl", **{"username": "morten"})
"SELECT * FROM tbl WHERE username = 'morten';"

>>> read("tbl", **{"user_type": 1, "user_group": "admin"})
"SELECT * FROM tbl WHERE user_type = '1' AND user_group = 'admin';"

ただし、SQL インジェクション攻撃には注意してください

コードの悪意のあるユーザーがこれを行うとどうなるかを見てください。

>>> read("tbl", **{"user_group": "admin'; DROP TABLE tbl; --"})
"SELECT * FROM tbl WHERE user_group = 'admin'; DROP TABLE tbl; --';"

独自のその場しのぎの ORM を作成するのは簡単ですが、表示されているものしか取得できません。入力を自分でエスケープする必要があります :)

于 2012-11-14T12:09:42.330 に答える
12

SQLAlchemy は、 Python から SQL を生成するための堅牢な式言語を提供します。

ただし、適切に設計された他のすべての抽象化レイヤーと同様に、生成されるクエリは、クエリ言語と挿入されるデータを単一の文字列に混在させるのではなく、バインド変数を介してデータを挿入します。このアプローチは、大規模なセキュリティの脆弱性を回避し、それ以外の場合は正しいことです.

于 2009-10-14T04:21:40.573 に答える
2

堅牢性のために、使用する言語に関係なく、準備済みステートメントを使用してユーザーが入力した値を送信することをお勧めします。:-)

于 2009-10-14T02:35:09.640 に答える
1

python db api 2.0には、接続オブジェクト用の「.execute」メソッドがあります。この関数でパラメーターを指定できます (パラメーターとクエリ文字列を区切るには、% 記号ではなくコンマを使用します)。

于 2009-10-14T02:51:38.837 に答える
1

一般に、パラメーターを手動で引用することは悪い考えです。ルールのエスケープに誤りがある場合はどうなりますか? エスケープが使用されている DB のバージョンと一致しない場合はどうなりますか? 一部のパラメーターをエスケープするのを忘れた場合や、エスケープが必要なデータを含めることができないと誤って想定した場合はどうなりますか? そのすべてが SQL インジェクションの脆弱性を引き起こす可能性があります。また、LOB 列に大きなデータ チャンクを渡す必要がある場合、DB は SQL ステートメントの長さに制限を設けることができます。そのため、Python DB API とほとんどのデータベース (初期の MySQLdb のように、データベースがこれをサポートしていない場合、Python DB API モジュールはパラメーターを透過的にエスケープします) は、ステートメントから分離されたパラメーターを渡すことができます。

.execute(操作[,パラメータ])

于 2009-10-14T04:23:07.517 に答える