2012-01-31 2 views
1

내가이 같은 SqlAlchem ​​y의 모델 뭔가 말해봐 :SqlAlchem ​​y의 관계는

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column, String, Integer, ForeignKey 
from sqlalchemy.orm import sessionmaker, relationship 
Base = declarative_base() 
Session = sessionmaker() 

class EmployeeType(Base): 
    __tablename__ = 'employee_type' 
    id = Column(Integer(), primary_key=True) 
    name = Column(String(20)) 

class Employee(Base): 
    __tablename__ = 'employee' 
    id = Column(Integer(), primary_key=True) 
    type_id = Column(Integer(), ForeignKey(EmployeeType.id)) 
    type = relationship(EmployeeType, uselist=False) 

session = Session() 
session.add(EmployeeType(name='drone')) 
session.add(EmployeeType(name='PHB')) 

내가 편의를 직원에서 직접 EmployeeType.name에 "관계"의 일종을 가지고 싶습니다를, 그래서 형식 이름이있는 경우 ID 또는 EmployeeType 개체를 찾는 단계를 건너 뛸 수 있습니다.

emp = Employee() 
emp.type_name = "drone" 
session.add(emp) 
session.commit() 
assert (emp.type.id == 1) 

그런 것이 가능합니까?

편집 : 나는 association_proxy이 도중에이 저를 얻을 수 있습니다 발견 :

class Employee(Base): 
    ... 
    type_name = association_proxy("type", "name") 

나는 그것에 할당하면 것을있는 유일한 문제 :

emp = session.query(Employee).filter_by(EmployeeType.name=='PHB').first() 
emp.type_name = 'drone' 

이는 employee_type.name 열이 아닌 수정을 employee.type_id 열입니다.

답변

1

내가 요나단의 일반적인 접근 방식에 동의,하지만 난 세션에 직원 개체를 추가하고 직원의 유형은 독립적으로 운영해야 설정 같은 느낌. 연습으로

from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column, String, Integer, ForeignKey 
from sqlalchemy.orm import sessionmaker, relationship 
Base = declarative_base() 
Session = sessionmaker() 

class EmployeeType(Base): 
    __tablename__ = 'employee_type' 
    id = Column(Integer(), primary_key=True) 
    name = Column(String(20)) 

class Employee(Base): 
    __tablename__ = 'employee' 
    id = Column(Integer(), primary_key=True) 
    type_id = Column(Integer(), ForeignKey(EmployeeType.id)) 
    type = relationship(EmployeeType) 

    @property 
    def type_name(self): 
     if self.type is not None: 
      return self.type.name 
     return None 

    @type_name.setter 
    def type_name(self, value): 
     if value is None: 
      self.type = None 
     else: 
      session = Session.object_session(self) 
      if session is None: 
       raise Exception("Can't set Employee type by name until added to session") 
      self.type = session.query(EmployeeType).filter_by(name=value).one() 
+0

의 "를 부착하여, 나는 또한, 세션에 직원을 부착하기 전에 TYPE_NAME 설정을 허용하는 버전을 채찍질 : 여기에 속성으로 TYPE_NAME가 그것을 설정하기 전에 세션에 추가해야합니다 구현입니다 after_attach "이벤트 리스너를 세션에 추가 : https://gist.github.com/1750520 –

2

나를 위해이 작업을 수행하는 방법을 작성하면됩니다.

class EmployeeType(Base): 
    __tablename__ = 'employee_type' 
    id = Column(Integer(), primary_key=True) 
    name = Column(String(20)) 

class Employee(Base): 
    __tablename__ = 'employee' 
    id = Column(Integer(), primary_key=True) 
    type_id = Column(Integer(), ForeignKey(EmployeeType.id)) 
    type = relationship(EmployeeType, uselist=False) 

    def __init__(self, type): 
     self.type = type 

    def add(self, type_name=None): 
     if type_name is not None: 
      emp_type = DBSession.query(EmployeeType).filter(EmployeeType.name == type_name).first() 
      if emp_type: 
       type = emp_type 
      else: 
       type = EmployeeType(name=type_name) 
     else: 
      type = None 
     DBSession.add(Employee(type=type)) 

그런 다음 당신이 할 :

Employee.add(type_name='boss')