我正在构建如下的继承表模式:
class Person(Base):
__tablename__ = 'people'
id = Column(Integer, primary_key=True)
discriminator = Column('type', String(50))
updated = Column(DateTime, server_default=func.now(), onupdate=func.now())
name = Column(String(50))
__mapper_args__ = {'polymorphic_on': discriminator}
class Engineer(Person):
__mapper_args__ = {'polymorphic_identity': 'engineer'}
start_date = Column(DateTime)
class Manager(Person):
__mapper_args__ = {'polymorphic_identity': 'manager'}
start_date = Column(DateTime)
import os
import sys
from sqlalchemy import Column, create_engine, ForeignKey, Integer, String, DateTime
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import func
from sqlalchemy.ext.declarative import declarative_base
try:
os.remove('test.db')
except FileNotFoundError:
pass
engine = create_engine('sqlite:///test.db', echo=True)
Session = sessionmaker(engine)
Base = declarative_base()
class People(Base):
__tablename__ = 'people'
discriminator = Column('type', String(50))
__mapper_args__ = {'polymorphic_on': discriminator}
id = Column(Integer, primary_key=True)
name = Column(String(50))
updated = Column(DateTime, server_default=func.now(), onupdate=func.now())
class Engineer(People):
__tablename__ = 'engineer'
__mapper_args__ = {'polymorphic_identity': 'engineer'}
id = Column(Integer, ForeignKey('people.id'), primary_key=True)
kind = Column(String(100), nullable=True)
Base.metadata.create_all(engine)
session = Session()
e = Engineer()
e.name = 'Mike'
session.add(e)
session.flush()
session.commit()
# works when updating the object
e.name = "Doug"
session.add(e)
session.commit()
# works using the base class for the query
count = session.query(People).filter(
People.name.is_('Doug')).update({People.name: 'James'})
# fails when using the derived class
count = session.query(Engineer).filter(
Engineer.name.is_('James')).update({Engineer.name: 'Mary'})
session.commit()
print("Count: {}".format(count))
注意:这是sql docs
中略有修改的示例如果我尝试为工程师更新name
,那么应该发生。
name
updated
列
醇>
目前,我想专注于数字1。下面的示例(如完整代码示例中所述)将导致无效的SQL
session.query(Engineer).filter(
Engineer.name.is_('James')).update({Engineer.name: 'Mary'})
我相信以上内容会产生以下结果:
UPDATE工程师SET名=?,更新= CURRENT_TIMESTAMP来自人WHERE people.name IS?
同样,这是无效的。该语句试图更新不正确的表中的行。 name
位于基表中。
我有点不清楚继承表应该如何工作,但似乎更新应该与派生对象透明地工作。这意味着,当我更新Engineer.name
查询Engineer
对象时,SQLAlchemy应该知道更新People
表。为了使事情复杂化,如果我尝试更新两个表中存在的列
session.query(Engineer).filter(
Engineer.name.is_('James')).update({Engineer.name: 'Mary', Engineer.start_date: '1997-01-01'})
我怀疑SQLAlchemy不会发出两个更新语句。