我有一个小问题,我认为应该可以通过SQL Alchemy轻松解决,但我似乎无法正确解决.我有两个表,一个是父表,另一个是子表.对于每个子记录,它需要一个唯一的ID,但仅具有唯一的父记录的上下文.
我正在使用声明式基础方法.
我使用FK和关联函数设置了父子关系.我要实现的目标是获得类似伪自动增量函数的功能,该功能将在“类别唯一名称”组中查找最大类别ID值,并将其递增一个.我尝试使用各种默认功能,但遇到的问题是插入时无法指定CategoryUniqueName.我找不到一种方法来传递CategoryItems.CategoryUniqueName的当前值,以便在尝试选择诸如func.max(CategoryItems.CategoryID)之类的内容时,查询查询具有正确的过滤器.如果我对查询进行硬编码,它就可以正常工作.这是我认为应该起作用的方法,但是再次,我找不到指定过滤器唯一值的方法.
unique_group='my_group'
result=con.query(func.max(CategoryItems.CategoryID)).filter(and_(
CategoryItems.CategoryUniqueName==unique_group,
)).one()
这些类如下所示.非常感谢一些有关如何在标准SQL Alchemy中完成此操作的指导.我知道我总是可以查找该值并直接在同一事务中直接指定它,但是我正在尝试提出一种独立的SQL Alchemy方法,该方法不需要其他逻辑.
class Category(Base):
__tablename__ = 'parent_table'
__table_args__ = {'mysql_engine':'InnoDB', 'useexisting':True}
CategoryUniqueName = Column(Unicode(255), primary_key=True)
CategoryGroupName = Column(Unicode(255), nullable=False)
CategoryGroupMemo = Column(UnicodeText)
SortOrder = Column(Integer, index=True)
IsLocked = Column(Boolean, default=0)
class CategoryItems(Base):
__tablename__ = 'child_table'
__table_args__ = {'mysql_engine':'InnoDB', 'useexisting':True}
CategoryUniqueName = Column(Unicode(255), ForeignKey(Category.CategoryUniqueName), primary_key=True)
CategoryID = Column(Integer, primary_key=True, autoincrement=False)
CategoryName = Column(Unicode(255), nullable=False, index=True)
CategoryMemo = Column(UnicodeText)
CategoryImage = Column(Unicode(255))
CategoryFlex1 = Column(Unicode(255), index=True)
CategoryFlex2 = Column(Unicode(255), index=True)
CategoryFlex3 = Column(Unicode(255), index=True)
SortOrder = Column(Integer, index=True)
category_group = relation(
Category,
backref=backref(
'items',
order_by=SortOrder,
collection_class=ordering_list('SortOrder'),
cascade="all, delete, delete-orphan"
))
解决方法:
我看到3种方法:
>最明显且有据可查的.使用before_insert()钩子替换插入的参数创建一个映射器扩展.
>将函数作为默认参数.可以使用带有上下文参数的此函数来调用所需的所有数据:context.compiled_parameters [0] [‘CategoryUniqueName’],context.connection.
>在server_default参数中传递FetchedValue()并使用触发器执行作业服务器端.
所有这些解决方案都有ddaa提及的竞争条件.在出现竞争情况的情况下,您的代码不会破坏数据库状态,但是如果正确定义了主键,则代码将因异常而失败(这对您的代码而言不正确!).在某些极少数情况下,某些应用程序失败(在Web应用程序中显示500页)可能是可以接受的.
请注意,您已将CategoryID定义为主键.这将不允许对CategoryUniqueName列的不同值重复使用相同的数字.您必须将其更改为2列的复合主索引.