SQLAlchemy ORM __init__方法vs.

时间:2013-10-08 21:09:21

标签: python sqlalchemy

SQLAlchemy ORM tutorial中,以下代码作为将映射到表的类的示例给出:

>>> from sqlalchemy import Column, Integer, String
>>> class User(Base):
...     __tablename__ = 'users'
...
...     id = Column(Integer, primary_key=True)
...     name = Column(String)
...     fullname = Column(String)
...     password = Column(String)
...
...     def __init__(self, name, fullname, password):
...         self.name = name
...         self.fullname = fullname
...         self.password = password
...
...     def __repr__(self):
...        return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)

如果namefullnamepassword由用户在实例化类时__init__方法设置,那么将它们声明为{{ 1}}对象(即作为类变量)?我不明白SQLAlchemy是如何以及何时能够使用这些信息的 - 它是以某种方式通过Column继承的'Base'类传递给SQLAlchemy模块的? (我认为不可能以这种方式将信息传递给一个单元 - 通过声明一个继承自另一个类的类。)

1 个答案:

答案 0 :(得分:20)

首先,你应该明白

class Foo(object):
    bar = ['baz']

class Foo(object):
    def __init__(self):   
        self.bar = ['baz']

意思是非常不同的东西,在第一种情况下,bar是一个类属性,它对于Foo的所有实例都是相同的,而类Foo本身(它是一个type的实例,而不是Foo),但在第二个中,barFoo的每个实例的属性,并且根本与该类无关! 。如果您同时尝试两者,并且附加到第一个bar,则更改将传播到Foo的每个实例,但对于第二个实例,只有您追加的实例才会进行更改。< / p>

你甚至可以设置两个!,你可以这样做:

class Foo(object):
    bar = 'baz'

    def __init__(self):   
        self.bar = 'quux'

这完全没有偏见。 Foo.bar == 'baz'Foo().bar == 'quux',您可以从type(Foo()).bar == 'baz'

的实例返回class属性

这意味着教程中__init__中的参数适用于User的实例,但Column定义适用于类

Sqlalchemy主要使用信息。它使用它,以便它可以生成以正确方式读取和写入数据库的SQL。这些定义仅适用于sqlalchemy将User的实例转换为数据库调用,或者在从数据库接收行时尝试创建User实例的情况。

您应该将类​​属性视为声明类型,将实例属性视为设置值

至于 sqlalchemy实际上使用那些信息时,Base中有一些特殊的魔法,几乎可以肯定来自{{ 1}}。该函数返回,该类使用元类,它可以跟踪何时定义了从sqlalchemy.ext.declarative.declarative_base()派生的新类。在类定义结束时,甚至在创建Base的实例之前,sqlalchemy会查看User类以查找它需要了解的列属性。