web-dev-qa-db-ja.com

SQLiteの変数テーブル名

質問:文字列コンストラクタを使用せずに変数をテーブル名として使用することは可能ですか?


情報:

私は現在、私の星のシミュレーションからのデータをカタログ化するプロジェクトに取り組んでいます。そのために、すべてのデータをsqliteデータベースにロードしています。かなりうまくいきますが、データベースに柔軟性、効率、使いやすさをさらに追加することにしました。私は後でシミュレーションにプラネトイドを追加する予定で、各星のテーブルが必要でした。この方法では、各太陽系の1〜4kの20mのいくつかのプラネタイドのテーブルをクエリする必要はありません。

文字列コンストラクターを使用するとSQLインジェクション攻撃に対して脆弱になるため、悪いと言われています。これらのデータベースにアクセスできるのは私だけなので、これは大した問題ではありませんが、ベストプラクティスに従いたいと思います。また、このようにして、同じような状況でプロジェクトが一般に公開されている場合、どうすればよいかがわかります。

現在私はこれをやっています:

cursor.execute("CREATE TABLE StarFrame"+self.name+" (etc etc)")

これは機能しますが、私はもっともっと何かをしたいと思います:

cursor.execute("CREATE TABLE StarFrame(?) (etc etc)",self.name)

これはおそらく不可能だと私は理解しています。私は何かのようなもので解決しますが

cursor.execute("CREATE TABLE (?) (etc etc)",self.name)

これがまったく不可能であれば、私はその答えを受け入れますが、誰かがこれを行う方法を知っている場合は、教えてください。 :)

私はpythonでコーディングしています。

38
Narcolapser

残念ながら、テーブルをパラメーター置換の対象にすることはできません(決定的なソースは見つかりませんでしたが、いくつかのWebフォーラムで見ました)。

インジェクションが心配な場合(おそらくそうなるはずです)、文字列を渡す前にクリーンアップする関数を記述できます。テーブル名だけを探しているので、英数字を受け入れて、)(][;,や空白などの句読点をすべて取り除くだけで安全です。基本的には、A-Z a-z 0-9のみを保持します。

def scrub(table_name):
    return ''.join( chr for chr in table_name if chr.isalnum() )

scrub('); drop tables --')  # returns 'droptables'
40
Donald Miner

データを複数のテーブルに分割しないでください。星型の列にインデックスを作成する場合、データに効率的にアクセスすることに問題はありません。

9
Ned Batchelder

テーブルを変数として作成する方法を探している人のために、私は同じ質問への別の回答からこれを得ました here

次のように言って動作します。それはすべてmhawkeから引用されます:

テーブル名にパラメーター置換を使用することはできません。自分でクエリ文字列にテーブル名を追加する必要があります。このようなもの:

query = 'SELECT * FROM {}'.format(table)
c.execute(query)

注意すべきことの1つは、テーブル名の値のソースです。それが信頼できないソースからのものである場合、たとえばユーザーの場合、SQLインジェクション攻撃の可能性を回避するために、テーブル名を検証する必要があります。 1つの方法は、DBカタログからテーブル名を検索するパラメーター化されたクエリを作成することです。

import sqlite3

def exists_table(db, name):
    query = "SELECT 1 FROM sqlite_master WHERE type='table' and name = ?"
    return db.execute(query, (name,)).fetchone() is not None
4
jubibanna

文字列フォーマットで試してください:

sql_cmd = '''CREATE TABLE {}(id, column1, column2, column2)'''.format(
            'table_name')
db.execute(sql_cmd)

置換'table_name'あなたの欲望と。

1
Windows Eight

あなたはこのようなものを使うことができますconn = sqlite3.connect() createTable = '''CREATE TABLE %s (# );''' %dateNow) conn.execute(createTable)

基本的に、たとえば現在の日付に従ってデータをいくつかのテーブルに分割する場合、日付に基づいてシステムを監視する必要があります。

createTable = '' 'CREATE TABLE%s(#);' ''%dateNow)は、コーディング言語に応じて、dateNowを変数として定義し、コーディングから現在の日付を取得できる変数dateNowでテーブルを作成することを意味します言語。

0
Davin Edison