5

MyResultいくつかのタブに対する複雑なクエリをデフォルト クラスではなくカスタム クラスにマップするように sqlalchemy に指示する方法を探していますRowProxy。これは簡単な作業例です

'''
create table foo(id integer, title text);
create table bar(id integer, foo_id integer, name text);
insert into foo values(0, 'null');
insert into foo values(1, 'eins');
insert into bar values(0,0, 'nullnull');
insert into bar values(1,0, 'einsnull');
insert into bar values(2,1, 'zweieins');
'''

および次のコード:

from sqlalchemy import *
from itertools import imap

db = create_engine('sqlite:///test.db')
metadata = MetaData(db)

class MyResult(object):
    def __init__(self, id, title, name):
        self.id = id
        self.title = title
        self.name = name

foo = Table('foo', metadata, autoload=True)
bar = Table('bar', metadata, autoload=True)

result = select([foo.c.id, foo.c.title, bar.c.name], foo.c.id == bar.c.foo_id).execute().fetchall()

今、結果行から MyResult へのマッピングを実行するように sqlalchemy に指示する方法を探しています。

row = result[0]
print type(row)
#<class 'sqlalchemy.engine.base.RowProxy'>
print row.items()
#[(u'id', 0), (u'title', u'null'), (u'name', u'einsnull')]

次のようなものを使用して手動でマッピングを行うことができることを知っています

my_result = imap(lambda x: MyResult(**x), result)

しかし、これは sqlalchemy で処理する方法ではないと感じています。

4

2 に答える 2

9

サンプルからわかるように、に対して1つ以上のFooが返されるFoo.id = 0ため、主キーの値が重複し、結果セットのサブセットのみが返されます。この場合、おそらくprimary_key他のBar列にも拡張する必要があります(含めるか、一意の場合は Bar.id使用します)。Bar.name

次に、from_statementリテラルSQLの使用に記載されているように)を使用してこれを実現できます。

sql_qry = select([foo.c.id.label("id"), 
                  foo.c.title.label("title"), 
                  bar.c.name.label("name")], 
                 foo.c.id == bar.c.foo_id)
my_result_qry = session.query(MyResult).from_statement(sql_qry)
for x in my_result_qry.all():
    print x

ただし、モデルMyResultをマッピングする必要があります。ダミーの(存在しない)テーブルまたはビューにマップできます。また、label列のsは、クラスの列定義と完全に一致する必要があるため重要です(コンストラクターは使用されません)。

于 2012-04-17T15:55:25.787 に答える
5

直接呼び出すとselect、ORM 機能が除外されます。クラスで使用する必要がありmapperます。MyResultあなたが持っているように、MyResultただの普通のクラスです。

このようなもの:

Foo = mapper(MyResult, foo)
Bar = mapper(MyResult, bar)  # NOTE: MyResult itself is unchanged by this

session = Session()
# query against the mapper class
result = session.query(Foo).filter(Foo.title == 'xyz').one()
print result.name
于 2012-04-16T21:52:54.537 に答える