9

SQLAlchemy ORM チュートリアルでは、テーブルにマップされるクラスの例として次のコードが示されています。

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

クラスがインスタンス化されるときにユーザーがメソッド内でとを設定する場合name、それらをオブジェクトとして (つまり、クラス変数として) 宣言する意味は何ですか? SQLAlchemy が情報をいつ、どのように使用できるかわかりません。継承元の「Base」クラスを介して SQLAlchemy モジュールに何らかの方法で渡されますか? (別のクラスから継承するクラスを宣言することによって、この方法でユニットに情報を渡すことが可能だとは思いませんでした)。fullnamepassword__init__ColumnUser

4

1 に答える 1

37

まず、それを理解する必要があります

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

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

非常に異なることを意味します。最初のケースでbarはクラス属性であり、 のすべてのインスタンスで同じでFooあり、クラスFoo自体 ( のインスタンスでありtype、 ではありませんFoo) が、2 番目barのケースでは各インスタンスの属性です。のFooであり、クラスにはまったく関連付けられていません。両方を試して に追加するとbar、最初は変更が のすべてのインスタンスに反映されますがFoo、2 つ目は追加したインスタンスだけが変更されます。

両方を設定することもできます!

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 は主にクラス情報を使用します。それを使用して、適切な方法でデータベースから読み書きする SQL を生成できるようにします。これらの定義は、sqlalchemy が のインスタンスUserをデータベース呼び出しに変換する場合、またはデータベースUserから行を受け取るときに のインスタンスを作成しようとする場合にのみ実際に適用されます。

クラス属性は型の宣言、インスタンス属性は値の設定と見なす必要があります。

sqlalchemy が実際にその情報をいつ使用するかについては、 には特別な魔法がありBase、これはほぼ確実にsqlalchemy.ext.declarative.declarative_base(). その関数は class を返し、クラスは派生元の新しいクラスがいつ定義されたかを追跡できるメタクラスを使用します。Baseクラス定義の最後で、 のインスタンスを作成する前であってもUser、sqlalchemy はUserクラスを調べて、知っておく必要がある列のプロパティを見つけます。

于 2013-10-08T21:23:33.653 に答える