を書くときに不用意に sqlite3 のデータ型をタイプミスしましたschema.sql
:
create table xxx(
id integer primary key autoincrement not null,
num integet
)
ご覧のとおり、 のinteget
はずですがinteger
、それでも機能します。つまり、データを挿入できます。なんで?integer
また、データベースを壊さずに修正するにはどうすればよいですか?
Pythonsqlite3
モジュールとデータベース自体の両方のドキュメントで説明されているように、sqlite3 は型指定されていません。INTEGER
文字列値を列に挿入したり、整数値を列に挿入したりできVARCHAR
ます。
ただし、sqlite には「列アフィニティ」と呼ばれる機能があり、列の型が INTEGER などの場合はパラメーターを数値的に処理しようとします。また、Python モジュールは、sqlite の各型を Python の型にマップしようとします。 INTEGER 列の場合、Python はそれを整数型にマップします。
それぞれのドキュメントで説明されているように:
宣言された型に文字列 "INT" が含まれている場合、INTEGER アフィニティが割り当てられます。
サイズに応じて INTEGER int または long
比較では大文字と小文字が区別されません。どのルールにも一致しないものは として扱われNUMERIC
、Python はstr
/ bytes
/として扱いbuffer
ます (バージョンによって異なります)。
したがって、sqlite 自体はinteget
のルールに一致するINTEGER
ため、整数値を格納して整数として取得できます。(もちろん'abc'
、 を格納することもできます。また、文字列として取得できます。) Python はこれをINTEGER
列として認識し、可能な場合は値を読み取りますint
。
質問の最後の部分については、sqlite3 は作成後に列の型を変更する方法を提供していません。実際、このALTER TABLE
コマンドでは、新しい列または制約を追加するか、テーブルの名前を変更することしかできません。
ライブ データベースを変更する必要がある場合は、次のように、適切な列を含む新しいテーブルを作成し、すべてをコピーして、古いテーブルを削除し、新しいテーブルの名前を変更する必要があります。
CREATE TABLE yyy(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, num INTEGER)
INSERT INTO yyy SELECT * FROM xxx
DROP TABLE xxx
ALTER TABLE yyy RENAME TO xxx
古いテーブルに挿入した文字列値はすべてコピーされます。その後、それらをフェッチするたびに、列の型が であるため、可能であればINTEGER
Python は、またはのままにするのではなく、 に変換しようとします。int
bytes
str