2013-01-18 141 views
3

我有一個簡單的播放器實體:SQLAlchemy的過濾器總是返回false

__tablename__ = 'player' 

_id = Column('id', SmallInteger, primary_key=True) 
_nickName = Column('nick_name', String) 

def __init__(self, nickName): 
    self._nickName = nickName 

@property 
def id(self): 
    return self._id 

@property 
def nickName(self): 
    return self._nickName.decode(encoding='UTF-8') 

@nickName.setter 
def nickName(self, nickName): 
    self._nickName = nickName 

當我這樣做:

players = session.query(Player).filter(Player.nickName=='foo') 

我打印players變種我得到這個:

SELECT player.id AS player_id, player.nick_name AS player_nick_name 
FROM player 
WHERE false 

顯然,當我在會話查詢結束時添加.first()時,結果爲None。 我嘗試過filter_by()並得到相同的結果。

任何幫助,歡迎。

+1

我可以問你爲什麼創建屬性而不是直接使用列? –

+0

如果您確實需要使用屬性,請選中['synonym'](http://docs.sqlalchemy.org/en/rel_0_8/orm/mapper_config.html#sqlalchemy.orm.synonym),['synonym_for'](http ://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/declarative.html#sqlalchemy.ext.declarative.synonym_for)和[hybrid](http://docs.sqlalchemy.org/en/rel_0_8/orm/ extensions/hybrid.html)擴展名。 –

+0

@Audrius,因爲這是我發現修復編碼問題的最簡單方法。如果你有這個想法,我會刪除getter/setter(我在窗戶上)。編輯:Eevve答案解決這個問題 – martinqt

回答

2

雖然使用@hybrid_property解決這個在一般情況下,你應該不需要手動解碼。只需將列類型設置爲Unicode而不是String,並假設您的服務器播放良好,則應正確取回unicode。你也不需要id屬性。

所以你應該需要這個類是:

class Player(Base): 
    __tablename__ = 'player' 

    id = Column(SmallInteger, primary_key=True) 
    nickName = Column(Unicode) 

(無論是列名和__init__參數可以自動生成的。)

如果有某種原因,你的數據庫是不處理的Unicode正確的,好吧,那是我們很樂意幫你解決的一個不同的問題。 :)

+0

這很好地工作('Unicode'和'@ hybrid_property')。謝謝。我手動指定列名稱,因爲該字段被命名爲「nick_name」和「屬性」「nickName」。對於'__init__'部分,這意味着我不需要定義這個方法來使我的當前'__init__'的行爲? – martinqt

+0

無論如何,Python變量和方法通常命名爲'with_underscores',爲什麼不把它叫做'nick_name'呢?是的,聲明性擴展會生成一個'__init__'給你,它帶有關鍵字參數,所以你可以說'Player(nick_name = u'martinqt')' – Eevee

+0

那是因爲我是python的新手,但是我做了C++和PHP我認爲我還有一些舊習慣。感謝您的建議,我會盡力爲我的下一個項目做到這一點。 – martinqt

2

您不能使用常規@property s作爲查詢參數。使用@hybrid_property代替:

from sqlalchemy.ext.hybrid import hybrid_property 

@hybrid_property 
def nickName(self): 
    return self._nickName.decode(encoding='UTF-8') 

@nickName.setter 
def nickName(self, nickName): 
    self._nickName = nickName 

這使得Player.nickName(等在類的屬性),在SQL表達式有用。