質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1167閲覧

python、SQLiteでtext型の値の格納に失敗

yk_00

総合スコア15

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/04/27 05:43

編集2019/04/27 06:08

前提・実現したいこと

pythonでSQLiteを使ってデータベースに接続し値を格納したい。
text型の変数your_nameを用いてデータベースに値を格納したい。

発生している問題・エラーメッセージ

text型の値の格納を試みた結果エラーが出ているが意味が分からない。
以下がエラー文です。
3度実行しています。
1番目がtext型の値格納(エラー)
ここで一度データベースを削除
2番目がint型の値格納(正常動作)
3番目がint型の値格納2回目(エラー)←投稿後解決、pyファイルではなくdbファイルを実行していた。

(base) C:\Users\Anonymous>cd web (base) C:\Users\Anonymous\web>cd cgi-bin (base) C:\Users\Anonymous\web\cgi-bin>python Debug.py Traceback (most recent call last): File "Debug.py", line 33, in <module> cur.execute("insert into studentTable(your_name)values({0});".format(input_your_name)) sqlite3.OperationalError: near "name": syntax error (base) C:\Users\Anonymous\web\cgi-bin>python Debug.py 5678 (base) C:\Users\Anonymous\web\cgi-bin>python Debug.db File "Debug.db", line 1 SQLite format 3 ^ SyntaxError: invalid syntax (base) C:\Users\Anonymous\web\cgi-bin>

該当のソースコード

python

1 2#! /usr/bin/env python3 3 4import sqlite3 5import csv 6import sys 7import io 8 9# windowsにおける文字化け回避 10sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") 11 12# 使用するデータベースを指定 13db_path = "Debug.db" 14 15# student.dbを使ってsqlite3を起動 16con = sqlite3.connect(db_path) 17 18# 属性名で値を取り出すように設定 19con.row_factory = sqlite3.Row 20 21# カーソル(sqlでデータベースを操作するやつ)を作成 22cur = con.cursor() 23 24htmlText = "" 25 26input_your_name = "your name" 27#input_your_name = 5678#Debug 28# 以下sqlの実行 29 30cur.execute( 31 "create table studentTable(your_name text);"#←your_nameの型をintに変えてみたら正常動作 32) 33 34cur.execute("insert into studentTable(your_name)values({0});".format(input_your_name)) 35 36cur.execute("select * from studentTable;") 37rows = cur.fetchall() 38 39# データベースから値を取り出す 40if not rows: 41 htmlText = "No Data" 42else: 43 for row in rows: 44 if str(row["your_name"]): 45 htmlText += str(row["your_name"]) 46 47# データベースとの接続を保存・終了 48con.commit() 49con.close() 50 51print(htmlText)

試したこと

text型ではなくint型なら正常に動作した。
ただ2回目を実行すると失敗した。←解決

補足情報(FW/ツールのバージョンなど)

python 3.7.3
anaconda prompt
windows10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2019/04/27 06:02

3回目のエラーは「python Debug.db」と.dbファイルに対してPython実行しているからではないでしょうか?
yk_00

2019/04/27 06:06

仰るとおりで… 気づきませんでした。 tabキーでの補完がpyファイルではなく新たに作られたdbファイルに補完されていたようです。
guest

回答1

0

ベストアンサー

フィールドがtext型の場合は"~ values('{0}')".fomrat~のように値をクオーテーションでくくる必要があります。

ただ、提示コードのように.formatでパラメータを渡してSQL文を作成すると、外部から意図しないSQL文を挿入される危険性があります。そこで
cur.execute("insert into studentTable(your_name)values(?)",(input_your_name,))
のようにプレースホルダを使い、ユーザー入力をエスケープ処理するようにしたほうがよいです。
参考:Pythonとデータベースの連携 - プレースホルダを使う

さらに、提示コードを複数回実行すると、すでにテーブル存在するのにテーブル作成しようとするためsqlite3.OperationalError: table studentTable already existsエラーが発生します。
これを回避するにはSQL文を"create table if not exists studentTable~"なりに修正する必要があります。
参考:[SQLserver][SQLite]テーブルの再作成

投稿2019/04/27 06:31

can110

総合スコア38266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yk_00

2019/04/27 06:53

シングルクォーテーションで囲むことで動作しました。 SQLインジェクション対策についても、table studentTable already existsもおっしゃる通りの方法で解決しました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問