Проблема с оператором SQLite DROP TABLE

РЕДАКТИРОВАТЬ: На данный момент я обнаружил ошибочную опечатку, которая была ответственной, и мой вопрос стал «Как опечатка, которую я сделал, вызвала ошибку, которую я получил» и «Как я мог бы лучше отладить это в будущем?»

Я настроил скрипт базы данных для SQLite (через pysqlite) следующим образом:

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

Я ожидаю, что это всегда будет работать без ошибок. Однако, если я запускаю этот сценарий дважды (используя метод sqlite.Connection.executescript), я получаю следующую ошибку:
OperationalError:table LandTerritory already exists

Пытаясь отладить это самостоятельно, я запускаю DROP TABLE LandTerritory самостоятельно и получаю: sqlite3.OperationalError: no such table: main.LandTerrito

Я предполагаю, что это как-то связано с "главным". часть, но я не уверен, что.

РЕДАКТИРОВАТЬ: Хорошо, PRAGMA foreign_keys=ON определенно здесь тоже замешан. Когда я создаю свое соединение, я включил Foreign_keys. Если я не включу это, я, кажется, не получаю эту ошибку.

И я должен был упомянуть, что в сценарии есть еще что-то, но я предположил, что ошибка возникает в этих первых двух утверждениях. Остальная часть скрипта делает то же самое, удаляет таблицу, определяет таблицу. В некоторых таблицах есть внешние ссылки на 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», несколько символов каким-то образом были обрезаны. Я предполагаю, что исправление этого может решить мою проблему.

Но я действительно сбит с толку тем, как ломаная строка в этой таблице привела к тому, что скрипт работал правильно в первый раз, а затем выдал мне ошибку, связанную с другой таблицей, когда я запускаю ее во второй раз, и как внешние ключи сыграли в этом роль.

Я думаю, повторяю вышеизложенное, есть ли лучший способ отладки такого рода вещей?


person Retsam    schedule 23.08.2012    source источник
comment
Я знаю, что вы ясно объяснили, как работает сценарий, но, чтобы быть уверенным, можете ли вы опубликовать его или хотя бы соответствующие части?   -  person    schedule 24.08.2012


Ответы (2)


Источник ошибки - ваша опечатка

REFERENCES LandTerrito

в строке 8 вашего скрипта. Это приводит к «отсутствующей» таблице LandTerrito в выражении CREATE TABLE LandAdjacent.

Если вы запустите два оператора CREATE TABLE, Sqlite не будет жаловаться. Но если у вас есть PRAGMA foreign_keys=ON; и вы попытаетесь выполнить оператор INSERT или DELETE для таблицы LandAdjacent, вы получите ошибку no such table: main.LandTerrito.

Однако из-за ограничений внешнего ключа DROP TABLE для LandTerritory приведет к DELETE в таблице LandAdjacent, что вызовет ошибку.

Следующие вещи помогут избежать ошибки

  1. установите PRAGMA foreign_keys=ON; перед удалением таблицы (проверено) или
  2. добавить фиктивную таблицу LandTerrito (проверено) или
  3. сбросьте сначала LandAdjacent, затем LandTerritory (проверено) или
  4. не используйте ON DELETE CASCADE (не проверено)
  5. и, конечно, исправление оригинальной опечатки.
person yonojoy    schedule 21.07.2015

Поместите «GO» (или любой другой эквивалент, используемый в SQLlite), чтобы завершить пакет между оператором drop table и оператором create.

person John Bingham    schedule 23.08.2012