数据库
首页 > 数据库> > python-SQL Alchemy默认值函数,用于在唯一的一组父子记录中模拟自动增量

python-SQL Alchemy默认值函数,用于在唯一的一组父子记录中模拟自动增量

作者:互联网

我有一个小问题,我认为应该可以通过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_pa​​rameters [0] [‘CategoryUniqueName’],context.connection.
>在server_default参数中传递FetchedValue()并使用触发器执行作业服务器端.

所有这些解决方案都有ddaa提及的竞争条件.在出现竞争情况的情况下,您的代码不会破坏数据库状态,但是如果正确定义了主键,则代码将因异常而失败(这对您的代码而言不正确!).在某些极少数情况下,某些应用程序失败(在Web应用程序中显示500页)可能是可以接受的.

请注意,您已将CategoryID定义为主键.这将不允许对CategoryUniqueName列的不同值重复使用相同的数字.您必须将其更改为2列的复合主索引.

标签:declarative,sqlalchemy,primary-key,auto-increment,python
来源: https://codeday.me/bug/20191107/2002160.html