【问题标题】:SQLAlchemy ORM __init__ method vsSQLAlchemy ORM __init__ 方法与
【发布时间】:2013-10-16 00:16:50
【问题描述】:

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__方法中设置,那么将它们声明为Column对象(即作为类变量)有什么意义?我不明白 SQLAlchemy 如何以及何时能够使用这些信息 - 它是否以某种方式通过 User 继承的“Base”类传递给 SQLAlchemy 模块? (我认为不可能以这种方式将信息传递给一个单元——通过声明一个继承自另一个类的类)。

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    首先,你应该明白

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

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

    意思很不一样,在第一种情况下,bar是一个类属性,对于Foo的所有实例都是一样的,而类Foo本身(也就是type的一个实例,不是Foo),但是在第二个中,barFoo 的每个实例的属性,并且根本与类无关!。如果您同时尝试这两种方法,并附加到 bar,首先,更改将传播到 Foo 的每个实例,但对于第二个,只有您附加到的实例才会具有该更改。

    你甚至可以同时设置!,你可以这样做:

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

    这完全没有争议。 Foo.bar == 'baz'Foo().bar == 'quux',您可以使用type(Foo()).bar == 'baz'从实例返回类属性

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

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

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

    至于什么时候 sqlalchemy 实际使用该信息,Base 中有一个特殊的魔法,几乎可以肯定来自sqlalchemy.ext.declarative.declarative_base()。该函数返回一个class,并且该类使用一个metaclass,它可以跟踪何时定义了派生自Base 的新类。在类定义结束时,甚至在您创建 User 的实例之前,sqlalchemy 就会查看 User 类以查找它需要了解的列属性。

    【讨论】:

    • 现在我更清楚了!最后一点,您解释了如何使用元类来跟踪从Base 派生的新类仍然相当混乱。你知道哪里有很好的解释它是如何工作的吗?
    • @MikeVella:您是否正在查看对元类的一般解释(如果是,see this question),或者特别是 SQLAlchemy 如何使用它们,请参阅 this questionthis article。希望这些会有所帮助。如果您有更具体的问题,请随时提出新的 StackOverflow 问题。
    猜你喜欢
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    • 2011-08-17
    • 2022-01-12
    • 1970-01-01
    • 2021-12-18
    • 2014-08-18
    相关资源
    最近更新 更多