【问题标题】:List database tables with SQLAlchemy使用 SQLAlchemy 列出数据库表
【发布时间】:2014-02-14 03:23:28
【问题描述】:

我想实现一个函数,它提供有关数据库中存在的所有表(及其列名)的信息(不仅是使用 SQLAlchemy 创建的那些)。在阅读文档时,在我看来这是通过反射完成的,但我没有设法让某些东西起作用。有关如何执行此操作的任何建议或示例?

【问题讨论】:

    标签: python database sqlalchemy


    【解决方案1】:

    从引擎开始:

    from sqlalchemy import create_engine
    engine = create_engine("postgresql://u:p@host/database")
    

    所有表/列名称的快速路径,使用检查器:

    from sqlalchemy import inspect
    inspector = inspect(engine)
    
    for table_name in inspector.get_table_names():
       for column in inspector.get_columns(table_name):
           print("Column: %s" % column['name'])
    

    文档:http://docs.sqlalchemy.org/en/rel_0_9/core/reflection.html?highlight=inspector#fine-grained-reflection-with-inspector

    或者,使用元数据/表格:

    from sqlalchemy import MetaData
    m = MetaData()
    m.reflect(engine)
    for table in m.tables.values():
        print(table.name)
        for column in table.c:
            print(column.name)
    

    文档:http://docs.sqlalchemy.org/en/rel_0_9/core/reflection.html#reflecting-all-tables-at-once

    【讨论】:

    • 使用inspectreflect 有什么好处(或缺点)吗?
    • 这里有点问题,但inspect 有效,而reflectreflect().keys.() 返回了NoneType 对象。不知道为什么。
    • 对我来说,inspect 不会返回完整的表格列表。它超级烦人,我看到了表分区,但没有看到该列表中的表。
    • SQLalchemy 中是否有内置方法来获得基于文本的模式表示?
    • Re: Evan - reflect 使用元数据信息更新元数据对象(在本例中为 m)。如果您在反射调用之前和之后查看 m.tables,您会在调用之前看到它是空的,并且在之后填充。
    【解决方案2】:

    嘿,我创建了一个小模块,可以帮助您轻松反映您使用 SQLAlchemy 连接的数据库中的所有表,看看:EZAlchemy

    from EZAlchemy.ezalchemy import EZAlchemy
    
    DB = EZAlchemy(
        db_user='username',
        db_password='pezzword',
        db_hostname='127.0.0.1',
        db_database='mydatabase',
        d_n_d='mysql'   # stands for dialect+driver
    )
    
    # this function loads all tables in the database to the class instance DB
    DB.connect()
    
    # List all associations to DB, you will see all the tables in that database
    dir(DB)
    

    【讨论】:

    • 这可以用来检查不是由 sqlalchemy 创建的数据库吗?
    • @user2682863:是的,它将显示您连接到的任何数据库的元数据。
    【解决方案3】:

    首先设置 sqlalchemy 引擎。

    from sqlalchemy import create_engine, inspect, text
    from sqlalchemy.engine import url
    
    connect_url = url.URL(
        'oracle',
        username='db_username',
        password='db_password',
        host='db_host',
        port='db_port',
        query=dict(service_name='db_service_name'))
    
    engine = create_engine(connect_url)
    
    try:
        engine.connect()
    except Exception as error:
        print(error)
        return
    

    就像其他人提到的,您可以使用 inspect 方法来获取表名。

    但就我而言,inspect 方法返回的表列表不完整。

    所以,我找到了另一种在 sqlalchemy 中使用纯 SQL 查询来查找表名的方法。

    query = text("SELECT table_name FROM all_tables where owner = '%s'"%str('db_username'))
    
    table_name_data = self.session.execute(query).fetchall()
    

    为了回答的完整性,这里是通过检查方法获取表名的代码(如果它适用于您的情况)。

    inspector = inspect(engine)
    table_names = inspector.get_table_names()
    

    【讨论】:

      【解决方案4】:

      我提出了另一种解决方案,因为在使用 schemaspostgres 的情况下,我对前面的任何一个都不满意。我通过查看pandas source code 一起破解了这个解决方案。

      from sqlalchemy import MetaData, create_engine
      from typing import List
      
      def list_tables(pg_uri: str, schema: str) -> List[str]:
          with create_engine(pg_uri).connect() as conn:
              meta = MetaData(conn, schema=schema)
              meta.reflect(views=True)
              return list(meta.tables.keys())
      

      为了获取架构中所有表的列表,您需要形成您的 postgres 数据库 uri pg_uri(例如,zzzeek 的答案中的 "postgresql://u:p@host/database")以及架构的名称 schema。因此,如果我们使用示例 uri 以及典型架构 public,我们将获得所有表和视图:

      list_tables("postgresql://u:p@host/database", "public")
      

      【讨论】:

        【解决方案5】:

        虽然reflection/inspection 很有用,但我无法从数据库中取出数据。我发现sqlsoup 更加用户友好。您使用 sqlalchemy 创建引擎并将该引擎传递给 sqlsoup.SQlSoup。即:

        import sqlsoup
        
        def create_engine():
            from sqlalchemy import create_engine
            return create_engine(f"mysql+mysqlconnector://{database_username}:{database_pw}@{database_host}/{database_name}")
        
        def test_sqlsoup():
            engine = create_engine()
            db = sqlsoup.SQLSoup(engine)
            # Note: database must have a table called 'users' for this example
            users = db.users.all()
            print(users)
        
        if __name__ == "__main__":
            test_sqlsoup()
        

        如果您熟悉 sqlalchemy,那么您就熟悉 sqlsoup。我用它从 wordpress 数据库中提取数据。

        【讨论】:

          猜你喜欢
          • 2017-09-30
          • 2012-09-11
          • 2020-06-01
          • 1970-01-01
          • 2020-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-27
          相关资源
          最近更新 更多