2011-10-07 32 views
2

我剛開始使用SQLAlchemy來處理現有的Postgres數據庫。我想要做的是自動加載兩個表,執行一個內部聯接並將一個子集的列映射到一個對象。爲了完成所有,但最後一部分,我已經寫了下面的代碼:SQLAlchemy - 自動加載表內連接的列映射子集

from sqlalchemy.orm import mapper, sessionmaker 
from sqlalchemy.sql import join, select 

engine = create_engine("postgresql://<username>:@localhost/<DBname>") 
metadata = Metadata(engine) 
Session = sessionmaker(engine) 
profiles = Table('userprofile',metadata,autoload=True) 
profilefields = Table('profilefield',metadata,autoload=True) 
class DBObj(object): 
    pass 
j = join(profiles,profilefields,profiles.c.fieldid==profilefields.c.fieldid) 
mapper(DBObj,j,properties={'fieldid':[profiles.c.fieldid,profilefields.c.fieldid]}) 
q = session.query(DBObj).all() 

我應該如何修改這個代碼斷言,我只想要一些指定的列映射到DBObj?我搜索的範圍很廣,似乎無法找到如何實現這一目標的例子。

回答

2

您需要將select()與所需列映射。映射一個join()原因SQLAlchemy的把它變成相應的select * from <join>

(跳過此塊:這只是創建測試夾具)

>>> from sqlalchemy.orm import mapper, sessionmaker 
>>> from sqlalchemy.sql import join, select 
>>> from sqlalchemy import * 
>>> # engine = create_engine("postgresql://<username>:@localhost/<DBname>") 
... engine = create_engine("sqlite:///:memory:") 
>>> engine.execute(r""" 
...  CREATE TABLE userprofile (
...   id integer primary key, 
...   fieldid integer, 
...   keep integer, 
...   discard integer 
... ) 
... """) 
<sqlalchemy.engine.base.ResultProxy object at 0x2390d90> 
>>> engine.execute(r""" 
...  CREATE TABLE profilefield (
...   id integer primary key, 
...   fieldid integer, 
...   keep integer, 
...   discard integer 
... ) 
... """) 
<sqlalchemy.engine.base.ResultProxy object at 0x2390e90> 
>>> metadata = MetaData(engine) 
>>> Session = sessionmaker(engine) 
>>> profiles = Table('userprofile',metadata,autoload=True) 
>>> profilefields = Table('profilefield',metadata,autoload=True) 
>>> engine.execute(profiles.insert({'fieldid': 1, 'keep': 2, 'discard': 3})) 
<sqlalchemy.engine.base.ResultProxy object at 0x23e9750> 
>>> engine.execute(profilefields.insert({'fieldid': 1, 'keep': 2, 'discard': 3})) 
<sqlalchemy.engine.base.ResultProxy object at 0x23e98d0> 
>>> class DBObj(object): 
...  def __repr__(self): 
...   return "DBobj" + str(self.__dict__) 
... 

>>> j = join(profiles, 
...   profilefields, 
...   profiles.c.fieldid==profilefields.c.fieldid) 

這裏的新零件:

>>> js = select([profiles.c.id, 
...    profiles.c.keep, 
...    profilefields.c.keep, 
...    profiles.c.fieldid, 
...    profilefields.c.fieldid], 
...    use_labels=True, 
...    from_obj=j) 
>>> mapper(DBObj,alias(js),properties={'fieldid':[profiles.c.fieldid,profilefields.c.fieldid]}) 
<Mapper at 0x23e9ad0; DBObj> 
>>> q = Session().query(DBObj).all() 
>>> q 
[DBobj{u'userprofile_keep': 2, u'userprofile_id': 1, '_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x23f08d0>, 'fieldid': 1, u'profilefield_keep': 2}] 
+0

非常感謝。這確實有幫助。 – Chris