_decl_class_registry 与 metadata.sorted_tables的区别
一、_decl_class_registry:
定义和存储内容:
_decl_class_registry
是declarative_base
的一个内部属性,它存储的是使用 SQLAlchemy 的声明式映射系统创建的类的映射信息。- 它是一个字典,其中键是类的名称(通常是带有模块名的限定名称,如
__main__.SomeClass
),值是对应的类对象。
使用场景:
- 当你需要在运行时动态查找已经声明的映射类时,这个属性就非常有用。例如,如果你想检查是否已经定义了某个类,或者想根据类名动态获取类对象进行一些操作,可以使用
_decl_class_registry
。 - 它主要用于 SQLAlchemy 的内部机制,例如在一些高级的元编程或动态加载场景中。但因为它是一个内部属性,其使用可能会受到 SQLAlchemy 版本更新和内部实现调整的影响。
示例代码:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class MyClass(Base):
__tablename__ = 'my_table'
id = Column(Integer, primary_key=True)
print(Base._decl_class_registry)
代码解释:
- 上述代码中,
declarative_base()
创建了Base
类,MyClass
继承自Base
并进行了表映射。 Base._decl_class_registry
会存储MyClass
及其类名作为键值对,例如{'__main__.MyClass': <class '__main__.MyClass'>}
。
二、metadata.sorted_tables:
定义和存储内容:
metadata
是Base
类的MetaData
对象,而sorted_tables
是metadata
的一个属性。sorted_tables
包含了一个列表,列表中的元素是表对象,这些表对象是按照表之间的依赖关系(如外键依赖)进行排序的。表对象包含了表的结构信息,例如表名、列、索引、外键等。
使用场景:
- 当你需要操作表的元数据时,
metadata.sorted_tables
是一个非常重要的属性。 - 你可以用它来遍历所有表,检查表的结构,包括表的列、索引、外键等信息。在创建表的时候,SQLAlchemy 会根据外键等依赖关系将表按正确的顺序添加到
sorted_tables
中,确保表的创建不会因为外键的依赖关系而出现错误。
示例代码:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer
Base = declarative_base()
class MyClass(Base):
__tablename__ = 'my_table'
id = Column(Integer, primary_key=True)
for table in Base.metadata.sorted_tables:
print(f"Table: {table.name}")
for column in table.columns:
print(f" Column: {column.name}")
代码解释:
- 这里使用
declarative_base()
创建了Base
类,MyClass
类映射到表my_table
。 Base.metadata.sorted_tables
存储了表对象列表。- 遍历
sorted_tables
时,对于每个表,打印表名,再遍历表的列并打印列名。
主要区别总结:
- 存储对象的性质:
_decl_class_registry
存储的是类对象,而metadata.sorted_tables
存储的是表对象。
- 数据结构:
_decl_class_registry
是一个字典,通过类名来查找类对象;metadata.sorted_tables
是一个列表,存储的是表对象,按表之间的依赖关系排序。
- 使用目的:
_decl_class_registry
主要用于查找已声明的映射类,适用于动态查找和元编程场景;metadata.sorted_tables
用于操作表的元数据,包括表的创建顺序和表的详细结构信息检查。
需要注意的是,在正常的 SQLAlchemy 应用开发中,通常更倾向于使用 metadata.sorted_tables
来处理表的元数据操作,因为它是 SQLAlchemy 提供的公开且稳定的接口。而 _decl_class_registry
由于是内部属性,其使用应该谨慎,避免因为 SQLAlchemy 的版本更新导致不可预期的问题。
总的来说,如果你关心的是类的信息和动态查找类,使用 _decl_class_registry
;如果你关心的是表的结构、表之间的依赖和表的创建顺序等表元数据相关信息,使用 metadata.sorted_tables
。