2

を書くときに不用意に sqlite3 のデータ型をタイプミスしましたschema.sql:


create table xxx(
    id integer primary key autoincrement not null,
    num integet
)

ご覧のとおり、 のintegetはずですがinteger、それでも機能します。つまり、データを挿入できます。なんで?integerまた、データベースを壊さずに修正するにはどうすればよいですか?

4

2 に答える 2

2

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

古いテーブルに挿入した文字列値はすべてコピーされます。その後、それらをフェッチするたびに、列の型が であるため、可能であればINTEGERPython は、またはのままにするのではなく、 に変換しようとします。intbytesstr

于 2013-05-28T09:55:17.877 に答える