我想在sqlite数据库中删除或添加列

我正在使用以下查询删除列。

ALTER TABLE TABLENAME DROP COLUMN COLUMNNAME

但它会产生错误

System.Data.SQLite.SQLiteException: SQLite error
near "DROP": syntax error

当前回答

http://www.sqlite.org/lang_altertable.html

正如您在图中看到的,只支持ADD COLUMN。不过,有一个(有点沉重的)变通方法:http://www.sqlite.org/faq.html#q11

其他回答

正如其他人指出的那样,sqlite的ALTER TABLE语句不支持DROP COLUMN,并且标准的做法是不保留约束和索引。

下面是一些python代码,在维护所有关键约束和索引的同时,可以通用地执行此操作。

请在使用之前备份您的数据库!这个函数依赖于修改原始的CREATE TABLE语句,可能有点不安全——例如,如果标识符包含嵌入的逗号或圆括号,它就会出错。

如果有人愿意提供一种更好的解析SQL的方法,那就太好了!

我发现了一个更好的方法来解析使用开源sqlparse包。如果有任何兴趣,我会张贴在这里,只要留下评论要求它…

import re
import random

def DROP_COLUMN(db, table, column):
    columns = [ c[1] for c in db.execute("PRAGMA table_info(%s)" % table) ]
    columns = [ c for c in columns if c != column ]
    sql = db.execute("SELECT sql from sqlite_master where name = '%s'" 
        % table).fetchone()[0]
    sql = format(sql)
    lines = sql.splitlines()
    findcol = r'\b%s\b' % column
    keeplines = [ line for line in lines if not re.search(findcol, line) ]
    create = '\n'.join(keeplines)
    create = re.sub(r',(\s*\))', r'\1', create)
    temp = 'tmp%d' % random.randint(1e8, 1e9)
    db.execute("ALTER TABLE %(old)s RENAME TO %(new)s" % { 
        'old': table, 'new': temp })
    db.execute(create)
    db.execute("""
        INSERT INTO %(new)s ( %(columns)s ) 
        SELECT %(columns)s FROM %(old)s
    """ % { 
        'old': temp,
        'new': table,
        'columns': ', '.join(columns)
    })  
    db.execute("DROP TABLE %s" % temp)

def format(sql):
    sql = sql.replace(",", ",\n")
    sql = sql.replace("(", "(\n")
    sql = sql.replace(")", "\n)")
    return sql

有一段时间不直接支持这一点,您需要遵循以下四个步骤:(1)创建一个temporary_table,(2)复制数据,(3)删除旧表,然后(4)重命名temporary_table。

但是现在支持这些特性,您所需要做的就是升级SQLite。

3.35.0 from 2021-03-12添加ALTER TABLE DROP COLUMN 3.25.0 from 2018-09-15新增ALTER TABLE RENAME COLUMN 3.2.0在2005-03-21添加了ALTER TABLE ADD COLUMN

请注意,仍然有一些边缘情况下,这些可能不起作用,例如,您不能删除主键列。有关详细信息,请参阅文档。当这些ALTER TABLE…COLUMN语句不起作用时,您可以退回到四步过程。

顺便说一下,文档中的四步流程实际上是十二步流程。但其中四个步骤非常重要,很容易出错,在这些文档中特别指出。

修改表SQLite

SQLite支持ALTER TABLE的一个有限子集。SQLite中的ALTER TABLE命令允许用户重命名表或向现有表添加新列。不能重命名列、删除列或从表中添加或删除约束。

您可以:

创建新表作为您要更改的表, 复制所有数据, 丢掉旧桌子, 重新命名新文件。

DB Browser for SQLite允许您添加或删除列。

在主视图中,选择Database Structure,单击表名。一个按钮Modify Table被启用,它会打开一个新窗口,您可以在其中选择列/字段并删除它。

正如其他人指出的那样

不能重命名列、删除列或添加或 从表中删除约束。

来源:http://www.sqlite.org/lang_altertable.html

而您总是可以创建一个新表,然后删除旧表。 我将尝试用一个例子来解释这种解决方法。

sqlite> .schema
CREATE TABLE person(
 id INTEGER PRIMARY KEY, 
 first_name TEXT,
 last_name TEXT, 
 age INTEGER, 
 height INTEGER
);
sqlite> select * from person ; 
id          first_name  last_name   age         height    
----------  ----------  ----------  ----------  ----------
0           john        doe         20          170       
1           foo         bar         25          171       

现在要从该表中删除列的高度。

创建另一个名为new_person的表

sqlite> CREATE TABLE new_person(
   ...>  id INTEGER PRIMARY KEY, 
   ...>  first_name TEXT, 
   ...>  last_name TEXT, 
   ...>  age INTEGER 
   ...> ) ; 
sqlite> 

现在从旧表复制数据

sqlite> INSERT INTO new_person
   ...> SELECT id, first_name, last_name, age FROM person ;
sqlite> select * from new_person ;
id          first_name  last_name   age       
----------  ----------  ----------  ----------
0           john        doe         20        
1           foo         bar         25        
sqlite>

现在删除person表并将new_person重命名为person

sqlite> DROP TABLE IF EXISTS person ; 
sqlite> ALTER TABLE new_person RENAME TO person ;
sqlite>

如果你使用。schema,你会看到

sqlite>.schema
CREATE TABLE "person"(
 id INTEGER PRIMARY KEY, 
 first_name TEXT, 
 last_name TEXT, 
 age INTEGER 
);