我需要一些帮助来了解继承在SQLAlchemy中的工作方式。我为具有一些基本功能的用户创建了基类。然后是一些特定的用户(管理员,cooluser,uncooluser)。每个都有独特的功能,因此我决定在SQLAlchemy中使用继承。问题是,我需要能够随时将用户升级为cooluser或uncooluser,并将cooluser降级为该用户。
class User(Base):
__tablename__ = 'tbl_users'
__table_args__ = {'mysql_engine': 'InnoDB'}
user_id = Column(Integer, primary_key = True, unique = True, nullable = False)
user_name = Column(String(100), nullable = False, unique = True)
password = Column(String(100), nullable = False)
user_type = Column('user_type', String(50))
first_name = Column(String(50), nullable = False)
last_name = Column(String(50), nullable = False)
address = Column(String(50), nullable = False)
city = Column(String(20), nullable = False)
postal_code = Column(String(10), nullable = False)
country_id = Column(Integer, ForeignKey(Contries.country_id))
country = relationship('Country', backref = 'users')
query = Session.query_property()
__mapper_args__ = {'polymorphic_on': user_type, 'polymorphic_identity': 'User'}
class CoolUser(User):
__tablename__ = 'tbl_cool_user'
__table_args__ = {'mysql_engine': 'InnoDB'}
__mapper_args__ = {'polymorphic_identity': 'CoolUser'}
cool_user_id = Column(Integer, ForeignKey(User.user_id, ondelete = 'CASCADE'), primary_key = True)
cool_user_balance = Column(Numeric(15, 3))
是否可以创建CoolUser而不在'tbl_users'中创建新行,而使用现有行?可以更改某些设置,以便在删除CoolUser时仅删除“ tbl_cool_user”中的条目,而不是“ tbl_user”中的条目吗?
我是否错过了SQLAlchemy中的继承点?
最佳答案
我是否错过了SQLAlchemy中的继承点?
我认为您通常会误用inheritance
概念,甚至不会在SA实现细节中误用。
在经典的Animal (Cat, Dog (Terier))
类型的层次结构中,您是否曾经想到过猫会被上/下级升级为狗,甚至是特定类型的狗?我不这么认为。此外,我可以很好地想象某些CoolUser
可能同时也是Administrator
。您将如何解决这种类型的关系?
因此,根据您的要求,继承不是解决该状态改变模型所要使用的概念。我建议Google为User-Role
关系和实现类型。您仍然必须解决存储特定于角色的数据思想的问题。
如@aquavitae所述:在SA中,您可以修改并更改user_type
。但是请注意,在这种情况下,将会发生以下情况:
当您从数据库中加载对象时,其类将反映新的类型(GOOD)
当您将对象降级(从CoolUser到User)时,对应于CoolUser的行将不会被删除(我认为它是BAD,但可能没问题)
当您升级对象(从User到CoolUser)时,将不会为CoolUser表创建新行,并且所有值均为NULL。这样,设置/添加未创建的行中存储的任何属性都将引发错误。当查询特定的子类时,您将不会再收到该对象,因为INNER JOIN
用于检索该对象。 (坏)
总之,不要将猫变成狗