4

編集:この時点で、原因となっている誤ったタイプミスを見つけました。私の質問は、「私が作成したタイプミスによって、受け取ったエラーがどのように発生したのか」と「将来、これをどのようにデバッグしたほうがよいでしょうか」になりました。

次のように(pysqliteを介して)SQLiteのデータベーススクリプトを設定しました。

DROP TABLE IF EXISTS LandTerritory;
CREATE TABLE LandTerritory (
  name   varchar(50) PRIMARY KEY NOT NULL UNIQUE, 
  hasSC  boolean NOT NULL DEFAULT 0
);

私はこれが常にエラーなしで実行されることを期待しています。ただし、このスクリプトを2回実行すると(sqlite.Connection.executescriptメソッドを使用して)、次のエラーが発生します。
OperationalError:table LandTerritory already exists

これを自分でデバッグしようとすると、私は自分で実行DROP TABLE LandTerritoryして次のようになります。 sqlite3.OperationalError: no such table: main.LandTerrito

これは「メイン」と関係があると思います。一部ですが、私にはわかりません。

編集:オーケーPRAGMA foreign_keys=ONは間違いなくここにも関わっています。接続を作成するときに、foreign_keysをオンにしました。オンにしないと、このエラーは発生しないようです。

スクリプトにはまだまだあることを述べておかなければなりませんが、これらの最初の2つのステートメントでエラーが発生していると想定していました。スクリプトの残りの部分は同じことを行い、テーブルを削除し、テーブルを定義します。いくつかのテーブルには、への外部キー参照がありLandTerritoryます。

sqliteエラーに関する行番号情報のようなものを取得する方法はありますか?それは本当に役に立ちます。

編集2:さて、これが最初のテーブルを参照するスクリプト内の別のテーブルです。

DROP TABLE IF EXISTS LandAdjacent;
CREATE TABLE LandAdjacent (
  tname1 varchar(50) NOT NULL,
  tname2 varchar(50) NOT NULL,
  PRIMARY KEY (tname1, tname2),
  /* Foreign keys */
  FOREIGN KEY (tname1)
    REFERENCES LandTerrito
    ON DELETE CASCADE
    ON UPDATE CASCADE, 
  FOREIGN KEY (tname2)
    REFERENCES LandTerritory(name)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);

これを見ると、「LandTerrito」が由来していることがわかりました。どういうわけか、いくつかのキャラクターが途切れていました。これを修正すると問題が解決するかもしれないと思います。

しかし、このテーブルの破線がスクリプトを最初に正しく実行し、2回目に実行したときに別のテーブルに関連するエラーが発生し、外部キーがこれにどのように影響したかについて、私は本当に混乱しています。

上から繰り返しますが、この種のものをデバッグするためのより良い方法はありますか?

4

2 に答える 2

1

エラーの原因はあなたのタイプミスです

REFERENCES LandTerrito

スクリプトの8行目。LandTerritoこれにより、CREATE TABLE LandAdjacentステートメントに「欠落している」テーブルが生じます。

2 つのステートメントを実行すると、CREATE TABLESqlite は文句を言いません。しかし、テーブルに対してorステートメントPRAGMA foreign_keys=ON;を実行しようとすると、エラーが発生します。INSERTDELETELandAdjacentno such table: main.LandTerrito

ただし、外部キー制約により、 DROP TABLEon the tableが発生し、エラーが発生します。LandTerritoryDELETELandAdjacent

次のことはエラーを回避します

  1. テーブルを削除する前に設定PRAGMA foreign_keys=ON;(テスト済み) または
  2. ダミーテーブルを追加するLandTerrito(テスト済み)または
  3. LandAdjacent最初にドロップしてからLandTerritory(テスト済み) または
  4. 使用しON DELETE CASCADEないでください(テストされていません)
  5. もちろん、元のタイプミスを修正します。
于 2015-07-21T12:55:16.740 に答える
-2

drop table ステートメントと create ステートメントの間のバッチを終了するには、「GO」(または SQLlite で使用される同等のもの) を配置します。

于 2012-08-23T23:00:58.533 に答える