【发布时间】:2012-08-13 08:20:17
【问题描述】:
我正在尝试找出一种方法来查找数据库中的表名(如果存在的话)。我发现可以从 sqlite cli 中使用:
>.tables
然后对于字段:
>PRAGMA TABLE_INFO(table_name)
这显然在 python 中不起作用。有没有办法用 python 做到这一点,还是我应该只使用 sqlite 命令行?
【问题讨论】:
标签: python sqlite database-schema
我正在尝试找出一种方法来查找数据库中的表名(如果存在的话)。我发现可以从 sqlite cli 中使用:
>.tables
然后对于字段:
>PRAGMA TABLE_INFO(table_name)
这显然在 python 中不起作用。有没有办法用 python 做到这一点,还是我应该只使用 sqlite 命令行?
【问题讨论】:
标签: python sqlite database-schema
您应该能够从sqlite_master 表中访问表名。
SELECT name FROM sqlite_master WHERE type='table';
不能直接访问列的名称。最简单的获取方式是查询表,从查询结果中获取列名。
SELECT * FROM table_name LIMIT 1;
【讨论】:
select sql from sqlite_master where type in ('table','index');
来自sqlite FAQ:
在 C/C++ 程序(或使用 Tcl/Ruby/Perl/Python 绑定的脚本)中,您可以通过在名为“SQLITE_MASTER”的特殊表上执行
SELECT来访问表和索引名称。每个 SQLite 数据库都有一个SQLITE_MASTER表,用于定义数据库的架构。SQLITE_MASTER表如下所示:CREATE TABLE sqlite_master ( type TEXT, name TEXT, tbl_name TEXT, rootpage INTEGER, sql TEXT );
所以要获取所有表名的列表,请执行:
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
要获取给定表的列名,请使用pragma table_info command:
此编译指示为命名表中的每一列返回一行。结果集中的列包括列名、数据类型、列是否可以为NULL,以及列的默认值。
这个命令在 python 中工作得很好:
>>> import sqlite3
>>> conn = sqlite3.connect(':mem:')
>>> for row in conn.execute("pragma table_info('sqlite_master')").fetchall():
... print row
...
(0, u'type', u'text', 0, None, 0)
(1, u'name', u'text', 0, None, 0)
(2, u'tbl_name', u'text', 0, None, 0)
(3, u'rootpage', u'integer', 0, None, 0)
(4, u'sql', u'text', 0, None, 0)
很遗憾,pragma 语句不适用于参数;您必须手动插入表名(确保它不是来自不受信任的来源并正确转义)。
【讨论】:
.description 方法的 Paul McNetts 回答一样显示?
pragma sql 语句像 select 语句一样返回行,所以如果有帮助,请像 select * from table_info where tablename = 'sqlite_master' 一样查看它。 :-)
.description 技巧返回的信息略有不同,详情请参阅PEP 249。我觉得如果你想自省一个 SQLite 数据库,那么使用pragma table_info 更直接,.description 给你执行查询的列信息,不一定是你查询的表中的所有列(例如select columna, columnb, 1 from table; 给你cursor.description 中的 3 个条目)。
要获取字段名称,请在查询后使用 cur.description:
import sqlite3.dbapi2 as sqlite
con = sqlite.connect(":memory:")
cur = con.cursor()
con.executescript("""
create table test (name, address);
insert into test (name, address) values ("Jer", "Monterey Street");
""")
cur.execute("select * from test where 1=0")
rs = cur.fetchall() ## will be [] because of where clause
field_names = [r[0] for r in cur.description]
【讨论】:
使用 sqlite 行对象。行对象具有可以为您提供架构的 keys()。
来自 docs.python.org
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from stocks')
<sqlite3.Cursor object at 0x7f4e7dd8fa80>
r = c.fetchone()
type(r)
<type 'sqlite3.Row'>
r
(u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14)
r.keys()
['date', 'trans', 'symbol', 'qty', 'price']
【讨论】:
这是我根据 Martijn 的回复编写的方便打印机:
def printSchema(connection):
for (tableName,) in connection.execute(
"""
select NAME from SQLITE_MASTER where TYPE='table' order by NAME;
"""
):
print("{}:".format(tableName))
for (
columnID, columnName, columnType,
columnNotNull, columnDefault, columnPK,
) in connection.execute("pragma table_info('{}');".format(tableName)):
print(" {id}: {name}({type}){null}{default}{pk}".format(
id=columnID,
name=columnName,
type=columnType,
null=" not null" if columnNotNull else "",
default=" [{}]".format(columnDefault) if columnDefault else "",
pk=" *{}".format(columnPK) if columnPK else "",
))
【讨论】:
我刚试过
SELECT name FROM my_db.sqlite_master WHERE type='table';
结合 Tom Kerr 的回答和在附加数据库上检索信息的尝试。起初它没有用。 原来我首先必须以这种方式附加另一个数据库:
ATTACH DATABASE 'file:my_other_database_file.db?cache=shared' as my_db;
否则数据库将无法获得附加数据库的sqlite_master 的读锁(并且所有查询都将成功,结果为零)。
只是一个提示,以防其他人偶然发现问题的那一部分。
【讨论】:
结果集有一个描述,您可以从中获取一些信息。它揭示了一些基本的元数据,例如列名和列数。
>>> rs = c.execute('''SELECT * FROM news WHERE 1=0''');
>>> dir(rs)
['__class__', '__delattr__', '__doc__', '__format__',
'__getattribute__', '__hash__', '__init__', '__iter__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', 'arraysize', 'close', 'connection',
**'description'**, 'execute', 'executemany', 'executescript', 'fetchall',
'fetchmany', 'fetchone', 'lastrowid', 'next', 'row_factory',
'rowcount', 'setinputsizes', 'setoutputsize']
>>> print(rs.description)
(('id', None, None, None, None, None, None),
('imageUrl', None, None, None, None, None, None),
('headline', None, None, None, None, None, None),
('who', None, None, None, None, None, None))
【讨论】:
要获取架构信息,恕我直言,以下也可以:
select sql from sqlite_master where type='table';
【讨论】:
connection = connect_db('./database_name.db')
table_names = [t[0] for t in connection.execute("SELECT name FROM sqlite_master WHERE type='table';")]
print(table_names)
【讨论】:
假设数据库名是my_db,表名是my_table,获取列名和数据类型:
con = sqlite.connect(my_db)
cur = con.cursor()
query = "pragma table_info({})".format(my_table)
table_info = cur.execute(query).fetchall()
它返回一个元组列表。每个元组都有顺序、列名和数据类型。
【讨论】: