Base.metadata如何在Sqlalchemy中工作?

时间:2019-10-28 20:40:25

标签: python sqlalchemy

代码/示例

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

这里metadataMetaData的定义是什么? 他们都是对象吗? MetaData()是函数还是其他?

根据SQLAlchemy文档MetaData,是:

  

一个容器对象,将描述的一个数据库(或多个数据库)的许多不同功能组合在一起。

但是,如果它是一个对象,那么如何将其作为类似于函数Metadata()的东西来运行?

摘要:

  • 如果Basemetadata是一个类,另一个是对象,该如何连接?
  • 如何运行命令(Base.metadata)?
  • metadataMetaData有什么区别?MetaData()的定义是什么?

1 个答案:

答案 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.spamFoo类的一个实例:

>>> 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的约束。