有没有办法从python中获取数据库的模式?

时间:2012-08-16 22:33:28

标签: python sqlite database-schema

我正试图找到一种方法来查找数据库中表的名称(如果存在)。我发现从sqlite cli我可以使用:

>.tables

然后是字段:

>PRAGMA TABLE_INFO(table_name)

这显然在python中不起作用。有没有办法用python做这个或者我应该只使用sqlite命令行?

10 个答案:

答案 0 :(得分:31)

来自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

  

此pragma为指定表中的每列返回一行。结果集中的列包括列名,数据类型,列是否为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语句不适用于参数;您必须手动插入表名(确保它不是来自不受信任的来源并正确转义)。

答案 1 :(得分:22)

您应该能够访问sqlite_master表中的表名。

SELECT name FROM sqlite_master WHERE type='table';

无法直接访问列的名称。获取它们的最简单方法是查询表并从查询结果中获取列名。

SELECT * FROM table_name LIMIT 1;

答案 2 :(得分:7)

这是我根据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 "",
            ))

答案 3 :(得分:2)

要获取字段名称,请在查询后使用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]

答案 4 :(得分:1)

使用sqlite行对象。行对象有key(),可以为您提供架构。

来自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']

答案 5 :(得分:1)

我刚试过

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的读锁定(并且所有查询都将成功,结果为零)。 只是暗示以防其他人偶然发现问题的这一部分。

答案 6 :(得分:1)

要获取架构信息,恕我直言,下面的方法也适用:

select sql from sqlite_master where type='table';

答案 7 :(得分:1)

建立与数据库的连接

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)

答案 8 :(得分:0)

结果集有一个描述,您可以从中获取一些信息。它会显示一些基本元数据,如列名和列数。

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

答案 9 :(得分:0)

假设数据库的名称为my_db,表的名称为my_table,以获取列的名称和数据类型:

<Files "file.txt">  
    Order Allow,Deny
    Allow from subdomain.site.com
    Deny from all
</Files>

它返回一个元组列表。每个元组都有顺序,列名和数据类型。