代码/示例
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
如果我运行print(Base)
,则会得到结果:
<class 'sqlalchemy.ext.declarative.api.Base'>
(即Base
是由函数declarative_base
创建的类)。
如果我运行print(Base.metadata)
,我会得到
Metadata(bind=engine(postgres//:user:password@host/database))
但是如果print(Base.metadata)
是一个类并且Base
是一个对象,metadata
到底会如何运行?
两者如何连接?
我可以理解元数据是否是一个类属性,但据我了解不是,所以这是如何工作的?
我错过了python语法中的某些内容吗?
查看元数据代码:
from sqlalchemy import MetaData
metadata = MetaData()
这里metadata
和MetaData
的定义是什么?
他们都是对象吗?
MetaData()
是函数还是其他?
根据SQLAlchemy文档MetaData
,是:
一个容器对象,将描述的一个数据库(或多个数据库)的许多不同功能组合在一起。
但是,如果它是一个对象,那么如何将其作为类似于函数Metadata()
的东西来运行?
Base
和metadata
是一个类,另一个是对象,该如何连接?Base.metadata
)?metadata
和MetaData
有什么区别?MetaData()
的定义是什么?答案 0 :(得分:2)
您太想了。在Python中,一切都是对象。类,函数,实例,数字,字符串,列表,字典,模块,..., 一切 。
您正在查看的SQLAlchemy对象没有什么不同,这些确实没有什么特别的。
是的,declarative_base()
函数返回一个新的类对象,该对象已分配给名称Base
。该类具有属性,并且其中一个属性名为metadata
。所有Python类都有属性,它们可以指向您喜欢的任何对象:
class Foo:
def __init__(self, name):
self.name = name
def print(self):
print(f"Hello, {self.name}!")
class Bar:
spam = Foo("World")
上述类Bar
具有属性spam
,它是类Foo
的实例。您可以在其上调用方法:
>>> Bar.spam.print()
Hello, World!
请注意,Bar
仍然是一个类,而Bar.spam
是Foo
类的一个实例:
>>> Bar
<class '__main__.Bar'>
>>> Bar.spam
<__main__.Foo object at 0x10d43c650>
>>> type(Bar.spam)
<class '__main__.Foo'>
由于Bar
只是另一个对象,因此您也可以将其传递,放入列表或从函数返回。 declarative_base()
为您构造了具有属性的类对象,并将其返回给调用方。
类似地,Base.metadata
只是MetaData
类的一个实例:
>>> type(Base.metadata)
<class 'sqlalchemy.sql.schema.MetaData'>
您的metadata = MetaData()
对象也是如此。
请注意,如果您仅运行Base = declarative_base()
而没有其他任何操作,则MetaData
实例实际上不会显示任何数据库连接信息:
>>> Base.metadata
MetaData(bind=None)
那是因为您实际上没有将元数据连接到数据库会话。一旦开始connecting a database with an engine并开始使用通过子类化Base
定义的模型,则元数据对象在某个时候将需要更多地了解数据库的详细信息(例如支持哪种SQL语言) ),并受SQLAlchemy的约束。