4

だから私はPythonでたくさんの配列データを持っています。むしろ、リストのリストがあります。この配列を MySQL データベースの単一のセルに格納しようとしています。JSON を使用してデータをシリアル化しようとしましたが、おそらく JSON の仕組みがわかりません。

したがって、データベースに接続した後:(アップストリームとダウンストリームの LONGTEXT および LONGBLOB データ型を試しました

cur = con.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS 963168MBV17A(Id INT AUTO_INCREMENT PRIMARY KEY, Rev INT, Part VARCHAR(15), SN INT(7), Date DATE, Time TIME, Iterations INT(3), Upstream LONGBLOB, Downstream LONGBLOB, ResultList LONGTEXT, Result CHAR(1), Report LONGBLOB)")

アップストリーム データとダウンストリーム データというリストのリストを取得して、次のようにします。

export_upstream = json.dumps(upstream_data)
export_downstream = json.dumps(downstream_data)

次に、SQL コマンドを実行します。

cur = con.cursor()    
sql_input = "INSERT INTO 963168MBV17A(Rev, Part, SN, Iterations, Date, Time, Upstream, Downstream, ResultList, Result, Report) VALUES('503', '100-120970-0031', '1594539', '%s', '%s', '%s', '%s', '%s', 0, P, 0" %(export_date, export_time, export_numtests, export_upstream, export_downstream)
cur.execute(sql_input)

Mordi (http://stackoverflow.com/questions/4251124/inserting-json-into-mysql-using-python) による回答を参照して、私も試しました:

export_upstream = json.dumps(json.dumps(upstream_data))
export_downstream = json.dumps(json.dumps(downstream_data))

しかし、関係なく、エラーが発生します:

Traceback (most recent call last):
  File "P:\Projects\testing database\scrap\test.py", line 83, in <module>
    cur.execute(sql_input)
  File "C:\Python27\lib\site-packages\MySQLdb\cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File "C:\Python27\lib\site-packages\MySQLdb\connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1")

さらに、私がするとき

print "about to execute(%s)" % sql_input

JSON オブジェクトが、あちこちにたくさんの一重引用符が付いた長い文字列として表示されていることがわかります (リストの場合と、文字列を表すために外側にある場合)。json.dumps(json.dumps(upstream_data)) を実行すると、内側の引用符が二重引用符 "" になり、前に \ 文字が付きます。それでも、同じエラーが発生します。

何か案は?そうでない場合、Python 配列/リスト データを単一の MySQL セルに保存するより良い方法はありますか?

ここに出力

4

5 に答える 5

6

パラメータ処理は MySQL ライブラリに任せる必要があります。これには、MySQL がステートメントを準備できるという追加の利点があり、挿入の繰り返しも高速になります。

cur = con.cursor()    
sql_input = "INSERT INTO 963168MBV17A(Rev, Part, SN, Iterations, Date, Time, Upstream, Downstream, ResultList, Result, Report) VALUES('503', '100-120970-0031', '1594539', ?, ?, ?, ?, ?, 0, P, 0"
cur.execute(sql_input, (export_date, export_time, export_numtests, export_upstream, export_downstream))

パラメーター化された SQL の (一部の) 詳細については、Python DB API 2.0 仕様を参照してください。サポートされている正確なパラメーター形式は、データベース アダプターごとに記載されているので、それも確認してください。たとえば、MySQLdb モジュールは Python 文字列の書式設定構文を模倣し、%sプレースホルダーとして使用します。

sql_input = "INSERT INTO 963168MBV17A(Rev, Part, SN, Iterations, Date, Time, Upstream, Downstream, ResultList, Result, Report) VALUES('503', '100-120970-0031', '1594539', %s, %s, %s, %s, %s, 0, P, 0"

その他の可能なパラメーター オプションは、数値 (:1, :2など)、名前 ( :foo, :bar)、またはその他の形式の Python 文字列形式、名前付き形式指定子 ( %(foo)s, %(bar)s) です。

于 2012-09-06T17:36:57.527 に答える
1

あなたが試みるかもしれないことの1つは、すべてのエスケープなどを処理するSQLAlchemyのSQL式生成を使用することです。さらに、多くのセキュリティ脆弱性(少なくともSQLデータベースへの挿入など)への対処を回避できます。あなたがやろうとしているようなインライン文字列補間を行うのではなく、クエリをパラメータ化します。

于 2012-09-06T17:47:37.517 に答える
1

あなたのコードで最初に目にする問題は次のとおりです。

sql_input = "INSERT INTO table (column) VALUES('%s');" % ( data )

これは絶対に行うべきではありません。文字列補間を使用しているため、SQLinjection や不正な形式の SQL から保護されません。

ほとんどの python db api は、次のようなプレースホルダー構文を使用します。

sql = "INSERT INTO table (column) VALUES( %s );"
values = (data,)
cur.execute(sql,values)

ステートメントと値を別々に渡すことに注意してください。API はエスケープとフォーマットを処理します。

辞書も許可するものもあります:

sql = "INSERT INTO table (column) VALUES( %(id)s );"
values = { 'id': 1 )
cur.execute(sql,values)

データベース API を適切に使用する方法を読んでください。これが最大の問題であり、おそらく他のすべての問題を引き起こしています。

于 2012-09-06T17:39:21.507 に答える
0

この問題は、SQL コマンドのエスケープ、または SQL コマンドの欠如によるものだと思います。

決して、決して、これをしないでください。

cursor.execute("INSERT INTO whatever VALUES (%s)" % "foo")

あなたが見ている問題は別として、そこにユーザー入力を渡すと安全ではありません (理由がわからない場合は、"Little Johnny Tables" を調べてください)。

代わりに、次のようにします。

cursor.execute("INSERT INTO whatever VALUES (%s)", ["foo"])

そして、MySql インターフェイスにエスケープを整理させます。

于 2012-09-06T17:36:22.920 に答える