SQLAlchemy中具有自定义逻辑的自增属性

1 投票
1 回答
1918 浏览
提问于 2025-04-15 12:28

我有一个简单的“发票”类,其中有一个“编号”属性,这个编号需要在用户保存发票时由应用程序来分配。这里有一些限制:

1) 这个应用程序是一个(轻量级的)客户端-服务器架构,所以负责分配编号的部分必须注意避免冲突。
2) 发票类还有一个“版本”属性,所以我不能使用简单的数据库自增字段。

我想通过一个自定义类型来实现这个功能,每次保存发票时都会触发这个类型。每当调用process_bind_param并传入None值时,它会调用某种单例来确定编号并避免冲突。这算是一个不错的解决方案吗?不过,我现在遇到了一个问题……这是我的自定义类型:

class AutoIncrement(types.TypeDecorator):
   impl = types.Unicode

   def copy(self):
       return AutoIncrement()

   def process_bind_param(self, value, dialect):
       if not value:
           # Must find next autoincrement value
           value = "1" # Test value :)
       return value

我现在的问题是,当我保存一张发票时,AutoIncrement把“1”设置为它的编号,但发票实例并没有更新为这个新编号……这是正常的吗?我是不是漏掉了什么?非常感谢你的时间!

(使用的是SQLA 0.5.3和Python 2.6,数据库是postgreSQL 8.3)

编辑:Michael Bayer告诉我,这种行为是正常的,因为TypeDecorators不处理默认值。

1 个回答

6

你有没有想过为什么不直接在你的列定义中使用一个 default= 参数呢?(这个参数可以是任意的 Python 可调用对象)。

def generate_invoice_number():
    # special logic to generate a unique invoice number

class Invoice(DeclarativeBase):
    __tablename__ = 'invoice'
    number = Column(Integer, unique=True, default=generate_invoice_number)
    ...

撰写回答