【问题标题】:Is there a way to get a schema of a database from within python?有没有办法从 python 中获取数据库的模式?
【发布时间】:2012-08-13 08:20:17
【问题描述】:

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

>.tables

然后对于字段:

>PRAGMA TABLE_INFO(table_name)

这显然在 python 中不起作用。有没有办法用 python 做到这一点,还是我应该只使用 sqlite 命令行?

【问题讨论】:

    标签: python sqlite database-schema


    【解决方案1】:

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

    SELECT name FROM sqlite_master WHERE type='table';
    

    不能直接访问列的名称。最简单的获取方式是查询表,从查询结果中获取列名。

    SELECT * FROM table_name LIMIT 1;
    

    【讨论】:

    • 第一部分效果很好,谢谢!我仍然不确定如何找到每个表的字段。我可以查询表格并找到里面的内容,但不是实际的字段名?
    • @tijko 看起来 Martjin 的答案有关于如何获取列名的 python 特定信息。我赞成他的回答!
    • 请注意,如果尚未向表中添加任何行,则第二个查询将不起作用。
    • 您可能想要包含索引:select sql from sqlite_master where type in ('table','index');
    【解决方案2】:

    来自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 语句不适用于参数;您必须手动插入表名(确保它不是来自不受信任的来源并正确转义)。

    【讨论】:

    • 很棒的答案,谢谢。我了解第一部分,但是我不了解 pragma_info。我有很多东西要学。我认为这些字段会像下面的 .description 方法的 Paul McNetts 回答一样显示?
    • @tijko:pragma sql 语句像 select 语句一样返回行,所以如果有帮助,请像 select * from table_info where tablename = 'sqlite_master' 一样查看它。 :-)
    • @tijko:.description 技巧返回的信息略有不同,详情请参阅PEP 249。我觉得如果你想自省一个 SQLite 数据库,那么使用pragma table_info 更直接,.description 给你执行查询的列信息,不一定是你查询的表中的所有列(例如select columna, columnb, 1 from table; 给你cursor.description 中的 3 个条目)。
    • @Martijin Pieters 是的,这很有帮助。找到它们后,应该用特定的表格尝试上面的那部分。感谢您的帮助!
    • 顺便说一句,我同意@MartijnPieters 的观​​点。我只是想展示另一种方法,用更少的数据库查询获取信息,并显示 python 代码。
    【解决方案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]
    

    【讨论】:

    • 嗨,保罗,谢谢。我只是想知道这条线是什么... rs = cur.fetchall() for rs 没有在其他任何地方引用
    【解决方案4】:

    使用 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']
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我刚试过

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:

            要获取架构信息,恕我直言,以下也可以:

            select sql from sqlite_master where type='table';
            

            【讨论】:

              【解决方案9】:

              建立与数据库的连接

              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)
              

              【讨论】:

                【解决方案10】:

                假设数据库名是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()
                

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-01-02
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-01-29
                  • 1970-01-01
                  • 2021-02-26
                  相关资源
                  最近更新 更多