【问题标题】:Table still exists even though database file has been deleted即使数据库文件已被删除,表仍然存在
【发布时间】:2020-09-17 22:04:52
【问题描述】:

每当我在学习 SQL 时测试我的 SQL 代码时,我都会尝试创建一个新的数据库,方法是参考我在创建新数据库之前删除的文件(我知道 @987654322 @ 并且如果使用文件不起作用,可能会使用它),但 SQLite 表示该表已经存在,只要它是我以前使用过的文件路径。例如,我使用“recipes3.db”路径并没有错误,但后来我删除了该文件并再次使用它,它说该表已经存在。我已经重新启动了解释器并重置了连接,但没有任何东西可以释放文件。正在预期目录中创建和删除文件。我不知道这些数据在哪里,以至于我无法重用路径。

我已经测试了更多,我可以sqlite3.connect("recipes2.db") 然后select * from recipes 并且在数据库中有一个具有该名称的表,正如我之前创建的那样,即使“recipes2.db”文件不存在,之前或运行命令后。使用“recipes5.db”,它没有看到任何这样的表,因为我没有使用过那个路径。现在该路径包含一个表。所以有一些我不知道的记忆。

我的代码:

def myPath(s):
    return "C:\\Users\\Kevin\\Desktop\\Python\\" + s

def loadDataIntoDatabase(database):
    sqliteClear(database, None)
    conn = sqlite3.connect(database)
    sqliteFile(conn, "recipe_tables_init.txt")
    cursor = conn.cursor()
    with open(myPath("recipe_list.txt"), "r") as file:
        for line in file:
            a = tuple(line.split(","))
            cursor.execute("insert into recipes values (?, ?, ?, ?)", a)
    with open(myPath("recipe_item_list.txt"), "r") as file:
        for line in file:
            a = tuple(line.split(","))
            cursor.execute("insert into recipe_items values (?, ?, ?, ?)", a)
    conn.commit()
    conn.close()

def sqliteClear(filename, conn):
    if not conn:
        conn = sqlite3.connect(filename)
    conn.close()
    s = myPath(filename)
    if os.path.isfile(s):
        os.remove(s)


def sqliteFile(conn, filename):
    cursor = conn.cursor()
    with open(myPath(filename), "r") as file:
        cursor.executescript(file.read())
    cursor.close()

编辑 2: recipe_table_init.txt的内容:

create table recipes (
    recipe_name varchar (30) primary key,
    category varchar (30),
    energy_required integer not null,
    enabled_or_disabled character (1) not null,
    constraint ed_constraint
        check (enabled_or_disabled in ('e', 'd'))
);

create table recipe_items (
    recipe_name varchar (30) not null,
    item_name varchar (30) not null,
    input_or_output character (1) not null,
    item_amount integer not null,
    constraint io_constraint
        check (input_or_output in ('i', 'o')),
    constraint branch primary key
        (recipe_name, item_name, input_or_output),
    constraint name_fk foreign key (recipe_name)
        references recipes (name)
            on delete cascade
);

我只是在*.db 这样的简单名称上调用loadDataIntoDatabase 并遇到此问题。我已经调用了其他函数,但即使只是在解释器的开头调用那个函数(然后再次导致表重复)也会导致问题,所以我认为它们不相关,除了它们在loadDataIntoDatabase 当然。

编辑: 我知道this question,但不幸的是它似乎与我正在做的事情无关。

【问题讨论】:

  • 请说明您是如何调用这些方法并显示recipe_tables_init.txt 的内容,这似乎是创建表格?
  • @Parfait 我添加了你的问题,谢谢你的建议。
  • 您的sqliteClear 函数会创建一个空文件,而不是删除它?空文件不一定是有效的 SQLite 数据库...
  • 另外,关于myPath是否在文件名上被调用,你是不一致的,所以你删除的文件和实际使用的文件可能不同。
  • sqlite3.connect(database) 调用使用文件名而不通过myPath 运行它。

标签: python sql sqlite


【解决方案1】:

如前所述,对任何 SQLite 数据库引用使用绝对路径。使用相对路径,新数据库位于脚本文件所在的任何位置。甚至使用带有原始字符串的os.path.join 来识别单个反斜杠。甚至考虑executemany

import os

def myPath(s): 
  db_path = r"C:\Users\Kevin\Desktop\Python"
  return os.path.join(db_path, s)

def loadDataIntoDatabase(database): 
   sqliteClear(myPath(database), None) 
   conn = sqlite3.connect(myPath(database))
   cursor = conn.cursor()

   sqliteFile(conn, "recipe_tables_init.txt") 

   with open(myPath("recipe_list.txt"), "r") as file: 
     rows = [line.split(",") for line in file]
     cursor.executemany("insert into recipes values (?, ?, ?, ?)", rows) 

   with open(myPath("recipe_item_list.txt"), "r") as file:
     rows = [line.split(",") for line in file] 
     cursor.executemany("insert into recipe_items values (?, ?, ?, ?)", rows)
             
   conn.commit()
 
   cursor.close()
   conn.close()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 2021-12-31
    • 2022-01-10
    • 1970-01-01
    • 2018-04-27
    • 1970-01-01
    相关资源
    最近更新 更多