Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法从python中获取数据库的模式?_Python_Sqlite_Database Schema - Fatal编程技术网

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

有没有办法从python中获取数据库的模式?,python,sqlite,database-schema,Python,Sqlite,Database Schema,我试图找到一种方法来查找数据库中的表名(如果有的话)。我发现通过sqlite cli,我可以使用: >.tables 然后,对于字段: >PRAGMA TABLE_INFO(table_name) 这显然不适用于python。有没有办法用python实现这一点,或者我应该只使用sqlite命令行?您应该能够从sqlite\u master表访问表名 SELECT name FROM sqlite_master WHERE type='table'; 列的名称不能直接访问。获取它

我试图找到一种方法来查找数据库中的表名(如果有的话)。我发现通过sqlite cli,我可以使用:

>.tables
然后,对于字段:

>PRAGMA TABLE_INFO(table_name)

这显然不适用于python。有没有办法用python实现这一点,或者我应该只使用sqlite命令行?

您应该能够从
sqlite\u master
表访问表名

SELECT name FROM sqlite_master WHERE type='table';
列的名称不能直接访问。获取它们的最简单方法是查询表并从查询结果中获取列名

SELECT * FROM table_name LIMIT 1;
从:

在C/C++程序(或使用Tcl/Ruby/Perl/Python绑定的脚本)中,您可以通过对名为“SQLITE_MASTER”的特殊表执行
SELECT
来访问表名和索引名。每个SQLite数据库都有一个定义数据库模式的
SQLite\u MASTER
表。
SQLITE\u 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;
要获取给定表的列名,请使用:

该杂注为命名表中的每列返回一行。结果集中的列包括列名、数据类型、列是否可以为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
语句不能处理参数;您必须手动插入表名(确保它不是来自不受信任的来源并正确转义)。

要获取字段名,请在查询后使用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行对象。row对象具有提供模式的键()

来自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']
conn.row\u工厂=sqlite3.row
c=连接光标()
c、 执行('select*from stocks')
r=c.fetchone()
类型(r)
R
(u'2006-01-05',u'BUY',u'RHAT',100.0,35.14)
r、 钥匙()
[‘日期’、‘运输’、‘符号’、‘数量’、‘价格’]

这是我根据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\u 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))

要获取模式信息,下面的IMHO也起作用:

select sql from sqlite_master where type='table';
建立到数据库的连接 打印表名
假设数据库的名称为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()

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

第一部分非常有用,谢谢!我仍然不确定如何找到每个表的字段。我可以查询表并找到其中的内容,但不是实际的字段名?@tijko的答案似乎包含了有关如何获取列名的python特定信息。我对他的回答投了赞成票!请注意,如果尚未向表中添加任何行,则第二个查询将不起作用。您可能希望包括索引:
selectsql fromsqlite\u master where-in('table','index')真棒的答案,谢谢。第一部分我理解,但布拉格语信息我不理解。我有很多东西要学。我原以为字段会像Paul McNetts使用下面的
.description
方法回答时那样显示?@tijko:
pragma
sql语句返回的行与select语句一样,因此如果有帮助,可以像从表信息中选择
select*,其中表名='sqlite\u master'
。:-)@tijko:The
.description
技巧返回的信息略有不同,有关详细信息,请参阅。我觉得,如果您想内省SQLite数据库,那么使用
pragma table_info
更直接,并且
.description
为您提供执行查询的列信息,而不一定是查询表中的所有列(例如,
从表中选择columna、columnb和1;
光标中提供3个条目。说明
)@Martijin Pieters是的,这是非常有用的。在找到它们之后,应该用一个特定的表来尝试上面的部分。谢谢你的帮助!顺便说一句,我同意@Martijin Pieters的观点。我只是想展示另一种方法,用更少的数据库查询来获取信息,并显示python代码。嗨,Paul,thanx。我只是想知道rs的行…rs=cur.fetchall()没有在其他任何地方引用
table_names = [t[0] for t in connection.execute("SELECT name FROM sqlite_master WHERE type='table';")]
print(table_names)
con = sqlite.connect(my_db)
cur = con.cursor()
query =  "pragma table_info({})".format(my_table)
table_info = cur.execute(query).fetchall()