简体   繁体   English

即使数据库文件已被删除,表仍然存在

[英]Table still exists even though database file has been deleted

I'm trying to create a fresh database each time I test my SQL code as I'm learning SQL, by referring to a file that I delete before making a new database in its place (I'm aware of :memory: and might use that if using files doesn't work), but SQLite says that the table already exists whenever it's a file path I've used before.每次我在学习 SQL 时测试我的 SQL 代码时,我都试图创建一个新的数据库,方法是参考我在创建新数据库之前删除的文件(我知道:memory:并且可能如果使用文件不起作用,请使用它),但 SQLite 表示该表已经存在,只要它是我以前使用过的文件路径。 For example, I used the "recipes3.db" path and it had no error, but then I deleted the file and used it again and it said the table already existed.例如,我使用了“recipes3.db”路径并且它没有错误,但后来我删除了该文件并再次使用它,它说该表已经存在。 I've restarted the interpreter and reset connections and nothing frees up the file.我重新启动了解释器并重置了连接,但没有任何东西可以释放文件。 The files are being created and deleted in the expected directory.正在预期目录中创建和删除文件。 I have no idea where this data is sticking around such that I can't reuse paths.我不知道这些数据在哪里,以至于我无法重用路径。

I've tested some more and I can sqlite3.connect("recipes2.db") then select * from recipes and there's a table with that name in the database, as I created before, even though the "recipes2.db" file doesn't exist, before or after running the command.我已经测试了更多,我可以sqlite3.connect("recipes2.db")然后select * from recipes并且数据库中有一个具有该名称的表,正如我之前创建的,即使“recipes2.db”文件没有'不存在,在运行命令之前或之后。 Going with "recipes5.db", it doesn't see any such table as I haven't used that path.使用“recipes5.db”,它没有看到任何这样的表,因为我没有使用过那个路径。 Now that path contains a table.现在该路径包含一个表。 So there's some memory somewhere that I don't know about.所以在某处有一些我不知道的记忆。

My code:我的代码:

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()

Edit 2: The contents of recipe_table_init.txt :编辑 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
);

I'm only calling loadDataIntoDatabase on simple names like *.db and getting this problem.我只是在像*.db这样的简单名称上调用loadDataIntoDatabase并遇到这个问题。 I've called the other functions, but even just calling that one function at the start of a interpreter (and then again to cause the table repeat) causes the problem, so I don't think they are relevant, apart from their use in loadDataIntoDatabase of course.我已经调用了其他函数,但即使只是在解释器开始时调用那个函数(然后再次导致表重复)也会导致问题,所以我认为它们不相关,除了它们在当然是loadDataIntoDatabase

Edit: I'm aware of this question but it unfortunately seems to have little to do with what I'm doing.编辑:我知道这个问题,但不幸的是,它似乎与我正在做的事情无关。

As discussed, use absolute paths for any SQLite database references.如前所述,对任何 SQLite 数据库引用使用绝对路径。 With relative paths, new databases is situated wherever script file resides.使用相对路径,新数据库位于脚本文件所在的任何位置。 Even use os.path.join with raw string to recognize single backslash.甚至使用os.path.join和原始字符串来识别单个反斜杠。 Even consider executemany :甚至考虑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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM