【发布时间】:2014-02-14 03:23:28
【问题描述】:
我想实现一个函数,它提供有关数据库中存在的所有表(及其列名)的信息(不仅是使用 SQLAlchemy 创建的那些)。在阅读文档时,在我看来这是通过反射完成的,但我没有设法让某些东西起作用。有关如何执行此操作的任何建议或示例?
【问题讨论】:
标签: python database sqlalchemy
我想实现一个函数,它提供有关数据库中存在的所有表(及其列名)的信息(不仅是使用 SQLAlchemy 创建的那些)。在阅读文档时,在我看来这是通过反射完成的,但我没有设法让某些东西起作用。有关如何执行此操作的任何建议或示例?
【问题讨论】:
标签: python database sqlalchemy
从引擎开始:
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'])
或者,使用元数据/表格:
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
【讨论】:
inspect 和reflect 有什么好处(或缺点)吗?
inspect 有效,而reflect 和reflect().keys.() 返回了NoneType 对象。不知道为什么。
嘿,我创建了一个小模块,可以帮助您轻松反映您使用 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 引擎。
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()
【讨论】:
我提出了另一种解决方案,因为在使用 schemas 的 postgres 的情况下,我对前面的任何一个都不满意。我通过查看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")
【讨论】:
虽然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 数据库中提取数据。
【讨论】: