0

MySQLの予約語の問題に対して、優れた「pythonic」および「SQL-Injection-free」ソリューションを探しています。

私は次のコードを持っています:

alter_sql = 'ALTER TABLE %s ADD COLUMN %s TEXT'      
cursor.execute(alter_sql, sql_params)

この問題は、列名が「index」、「int」、「limit」などの場合に発生します。

MySQLシェルで私ができること:

ALTER TABLE test ADD COLUMN test.limit;

また

ALTER TABLE test ADD COLUMN `limit`;

だがしかし

ALTER TABLE test ADD COLUMN 'test.limit';

PythonとMySQLdbでそれをどのように達成できますか?

4

2 に答える 2

2

多分これはうまくいくでしょう:

alter_sql = 'ALTER TABLE `%s` ADD COLUMN `%s` TEXT'

更新:MySQLdbはこれが文字列リテラルであると想定しているため、この方法でパラメータをバインドすると一重引用符が追加されるため、これは機能しないようです。

または、列名の前にテーブル名を追加できますか?

table_name = MySQLdb.escape_string(table_name)
escaped_column_name = MySQLdb.escape_string(column_name)
column_name = '`%s`.`%s`' % (table_name, escaped_column_name)

alter_sql = 'ALTER TABLE %s ADD COLUMN %s TEXT' % (table_name, column_name)

このように、それらをバインドして一重引用符を追加しないように、手動でエスケープする必要があります。

于 2012-05-16T11:35:45.977 に答える
0

ここから:

%sプレースホルダーマーカーを使用し、適切な値をそれらにバインドすることで、同じステートメントを発行できます。

cursor.execute("""UPDATE animal SET name = %s
                  WHERE name = %s
               """, ("snake", "turtle"))
print "Number of rows updated: %d" % cursor.rowcount

前のexecute()呼び出しの形式について、次の点に注意してください。

  • %sプレースホルダーマーカーは、ステートメント文字列に挿入される値ごとに1回出現する必要があります。
  • %sマーカーを引用符で囲むことはできません。MySQLdbは、必要に応じて見積もりを提供します。
  • execute()のステートメントstring引数に続いて、プレースホルダーにバインドされる値を含むタプルを、文字列内に表示される順序で指定します。値xが1つしかない場合は、それを(x、)として指定して、単一要素のタプルを示します。
  • Python None値をプレースホルダーにバインドして、SQLNULL値をステートメントに挿入します。

したがって、それに基づいて、引数を前処理して、予約済みキーワードのリストに含まれているかどうかを確認し、含まれている場合は、たとえば、テーブル名の前に列名を付ける必要があります。

RESERVED_KEYWORDS = ['LIMIT', 'INT', 'INDEX']
table_name = 'TESTING'
column_name = 'LIMIT'
if column_name in RESERVED_KEYWORDS:
    column_name = '%s.%s' % (table_name, column_name)
sql_params = [table_name, column_name]
alter_sql = 'ALTER TABLE %s ADD COLUMN %s TEXT'      
cursor.execute(alter_sql, sql_params)
于 2012-05-16T12:00:45.880 に答える