【问题标题】:Automatically truncate strings in sqlalchemy's ORM (postgresql database)自动截断 sqlalchemy 的 ORM(postgresql 数据库)中的字符串
【发布时间】:2021-01-09 23:11:52
【问题描述】:

如何在数据模型中跨多个属性自动截断字符串值,而不为每个属性显式定义 @validates 方法?

我当前的代码:

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import validates

class MyModel:
    __tablename__ = 'my_model'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(40), nullable=False, unique=True)

    # I can "force" truncation to my model using "validates"
    # I'd prefer not to use this solution though...
    @validates('name')
    def validate_code(self, key, value):
        max_len = getattr(self.__class__, key).prop.columns[0].type.length
        if value and len(value) > max_len:
            value = value[:max_len]
        return value

我担心我的 ORM 将跨越许多表和字段,并且在字符串长度验证中包含属性存在很高的疏忽风险。简而言之,我需要一个可以扩展的解决方案。 理想情况下,我的会话配置中的某些内容会自动截断太长的字符串...

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    您可以 create a customised String type 在插入时自动截断其值。

    import sqlalchemy.types as types
    
    
    class LimitedLengthString(types.TypeDecorator):
        impl = types.String
    
        def process_bind_param(self, value, dialect):
            return value[:self.impl.length]
    
        def copy(self, **kwargs):
            return LimitedLengthString(self.impl.length)
    
    
    class MyModel:
        __tablename__ = 'my_model'
    
        id = Column(Integer, primary_key=True, autoincrement=True)
        name = Column(LimitedLengthString(40), nullable=False, unique=True)
    

    扩展类型仍将在数据库中创建VARCHAR(40),因此应该可以在您的代码中将String(40) 替换为LimitedLengthString(40)* 而无需进行数据库迁移。


    * 您可能想选择一个较短的名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2017-08-14
      • 2015-04-18
      • 2015-04-29
      相关资源
      最近更新 更多