假设我有一个类似这样的SqlAlchemy模型:
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'))
我想要有某种关系"从Employee直接到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列。
答案 0 :(得分: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')
答案 1 :(得分:2)
我同意Jonathan的一般方法,但我想在会话中添加一个员工对象,并且设置员工类型应该是独立的操作。这是一个将type_name作为属性的实现,需要在设置之前添加到会话:
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()