2011-10-13 3 views
0

나는 클래스가 :

from sys import stderr 
from elixir import * 
from types import * 

class User(Entity): 
    using_options(tablename="users") 
    first_name = Field(String(50)) 
    middle_name = Field(String(50)) 
    last_name = Field(String(50)) 

    def __get_name__ (self): 
     first_name = self.first_name if self.first_name is not None else "" 
     middle_name = self.middle_name if self.middle_name is not None else "" 
     last_name = self.last_name if self.last_name is not None else "" 
     return " ".join((first_name, middle_name, last_name)).strip() 

    def __set_name__ (self,string): 
     first_name = "" 
     middle_name = "" 
     last_name = "" 
     split_string = string.split(' ') 
     if len(split_string) == 1: 
      first_name = string 
     elif len(split_string) == 2: 
      first_name, last_name = split_string 
     elif len(split_string) == 3: 
      first_name, middle_name, last_name = split_string 
     else: #len(split_string) > 3: 
      first_name = split_string[0] 
      last_name = split_string[-1] 
      middle_name = " ".join(split_string[1:-2]) 
     self.first_name = first_name 
     self.middle_name = middle_name 
     self.last_name = last_name 

    name = property(__get_name__,__set_name__) 

나는 다음과 같은 쿼리를 실행하고 싶습니다 :

def get_user(user): 
    found = None 
    if type(user) in [IntType,StringType]: 
     if type(user) is StringType: 
      where = or_(User.first_name==user, 
         User.middle_name==user, 
         User.last_name==user, 
         User.name==user) 
      qry = User.query.filter(where) 
     elif type(user) is IntType: 
      where = or_(User.id==user, 
         User.employee_id==user) 
      qry = User.query.filter(where) 
     try: 
      found = qry.one() 
     except NoResultFound: 
      print >> stderr, "Couldn't find '%s'" % user 
    elif type(user) == User: 
     found=user 
    return found 

을하지만, 그 결과를 '거짓'PLAC에서

SELECT users.first_name AS users_first_name, 
     users.middle_name AS users_middle_name, 
     users.last_name AS users_last_name 
FROM users 
WHERE users.first_name = 'Joseph' 
    OR users.middle_name = 'M' 
    OR users.last_name = 'Schmoe' 
    OR false 

공지 사항 : SQL 쿼리는 다음과 같이 보입니다 e User.name 필드의.

SELECT users.name 
FROM users 
WHERE users.name = 'Joseph M Schmoe' 

편집 : 다음은 내가 같이하는 SQL 쿼리를하고 싶습니다 어떻게 생각

sqlalchemy.exc.OperationalError: (OperationalError) no such column: false 

된다

이 오류를 받고 있어요 원하는/초 SQL 쿼리를 'first_name', 'middle_name', 'last_name'의 연결에 해당하는 데이터베이스 내에 'name'필드를 만드는 일종의 수동적 방법.

편집 2 다음과 같이하면 거의 나를 얻을 수 있다고 생각합니다. 그러나 나는 여전히 적절한 표현으로 고심하고있다.

편집 3 : 내가 원하는 작업을하는 것처럼 보입니다. 그래서 저는 그것을 대답으로 포함시키고 있습니다.

+0

User.name에게 그와 같은 @property 데프 이름 (자기) : 반환 foo는 #이 문없이 쿼리를 실행하려고 User.name = = 사용자가 속성의 유형을 묻기 때문에 사용자 –

+0

@ rob.alarcon :;) 쿼리는 추가 선없이 잘 실행됩니다. 그러나 쿼리를 수행 할 때 ORM을 사용하여 쿼리 내에서 사용 가능한 속성을 만들고 싶습니다. –

+0

'__set_name__'은 이제 파이썬 3.6에서 예약 된 특별한 메소드 이름입니다 –

답변

2
from sqlalchemy.ext.hybrid import hybrid_property 

@hybrid_property 
def name (self): 
    first_name = self.first_name if self.first_name is not None else "" 
    middle_name = self.middle_name if self.middle_name is not None else "" 
    last_name = self.last_name if self.last_name is not None else "" 
    return " ".join((first_name, middle_name, last_name)).strip() 

@name.setter 
def name (self,string): 
    first_name = "" 
    middle_name = "" 
    last_name = "" 
    split_string = string.split(' ') 
    if len(split_string) == 1: 
     first_name = string 
    elif len(split_string) == 2: 
     first_name, last_name = split_string 
    elif len(split_string) == 3: 
     first_name, middle_name, last_name = split_string 
    else: #len(split_string) > 3: 
     first_name = split_string[0] 
     last_name = split_string[-1] 
     middle_name = " ".join(split_string[1:-2]) 
    self.first_name = first_name 
    self.middle_name = middle_name 
    self.last_name = last_name 

익스프레션 부분은 여기에 있습니다 :

@name.expression 
def name (cls): 
    f = cls.first_name 
    m = cls.middle_name 
    l = cls.last_name 
    return f+' '+m+' '+l 
2

속성을 정의하면 개체를 할당 한 후에 사용할 수 있습니다.

참고 : 나는

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column, Integer, DateTime, String 
from datetime import datetime 

Base = declarative_base() 
class User(Base): 
    first_name = Column('first_name', String) 
    middle_name = Column('middle_name', String) 
    last_name = Column('last_name', String) 

    def __get_name__ (self): 
     first_name = self.first_name if self.first_name is not None else "" 
     middle_name = self.middle_name if self.middle_name is not None else "" 
     last_name = self.last_name if self.last_name is not None else "" 
     return " ".join((first_name, middle_name, last_name)).strip() 

    def __set_name__ (self,string): 
     first_name = "" 
     middle_name = "" 
     last_name = "" 
     split_string = string.split(' ') 
     if len(split_string) == 1: 
      first_name = string 
     elif len(split_string) == 2: 
      first_name, last_name = split_string 
     elif len(split_string) == 3: 
      first_name, middle_name, last_name = split_string 
     else: #len(split_string) > 3: 
      first_name = split_string[0] 
      last_name = split_string[-1] 
      middle_name = " ".join(split_string[1:-2]) 
     self.first_name = first_name 
     self.middle_name = middle_name 
     self.last_name = last_name 

    name = property(__get_name__,__set_name__) 

그래서 first_name, middle_name and last_name은 클래스 속성입니다 내 편의를 위해 코드를 변경합니다. 속성을 정의 할 때 해당 객체의 인스턴스가 필요합니다.

In [13]: User.first_name 
Out[13]: Column('first_name', String(),) 

In [14]: User.name 
Out[14]: <property object at 0x26fef70> 

는 위의 예에서 당신은 차이를 볼 수 있습니다. 해당 속성이나 속성의 필드를 설정할 때까지 항상 비어있게됩니다.

당신은 당신이 속성을 사용할 수 있습니다이 후

In [16]: u1 = User() 

In [17]: u1.name = "first middle last" 

In [18]: u1.name 
Out[18]: 'first middle last' 

In [19]: u1.first_name 
Out[19]: 'first' 

을 제공해야합니다.

이렇게하면 문제를 이해하는 데 도움이됩니다. 귀하의 재산은 귀하가 클래스별로 접근 할 수없는 예와 관련이 있습니다.

+1

Elixir에서 Sqlalchemy로 옮겼을 때, 당신이 내 이슈를 난독 화했을지도 모른다. 클래스 속성 인 것처럼 이름을 사용하고 싶습니다. SQA 예제 [here] (http://www.sqlalchemy.org/docs/05/mappers.html#sql-expressions-as-mapped-attributes)가 있지만, 나는 그것을 Elixir에서 끝내고 싶다. 적절한 사용은 ColumnProperty [여기] (http://elixir.ematia.de/apidocs/elixir.properties.ColumnProperty.html)와 관련이 있다고 생각합니다. 그러나 문서 자체가 도움이되지는 않습니다. Google은 [여기] (http://tinyurl.com/6blgyxw)를 가지고 있지만 문자열을 다루지 않습니다. –

+1

'__set_name__'은 이제 파이썬 3.6에 예약 된 메소드 이름입니다. –

+0

감사합니다 @AnttiHaapala가 내 대답을 업데이트해야합니다 :) – Nilesh