【问题标题】:Truncating too long varchar when inserting to MySQL via SQLAlchemy通过 SQLAlchemy 插入 MySQL 时截断太长的 varchar
【发布时间】:2015-11-28 15:09:13
【问题描述】:

我通过 SQLAlchemy 模型将数据插入 MySQL。最近,这个应用程序在配置了STRICT_TRANS_TABLES 的 MySQL 上运行,并且应用程序偶尔会因为 Data too long for column 错误而失败。

我知道我可以为我的会话禁用 strict sql_mode(比如这里MySQL too long varchar truncation/error setting),

但我很好奇 SQLAlchemy 是否可以为列数据强制执行最大 String() 长度。文档说,String() 长度仅适用于CREATE TABLE。我的问题:

  1. 是否可以在 SQLAlchemy 中强制执行最大长度(截断过长的字符串)?
  2. 我可以为单个列或仅为所有表/数据库中的所有列设置它吗?

【问题讨论】:

    标签: python mysql sqlalchemy


    【解决方案1】:

    如果您想通过在 python/sqlalchemy 端自动截断enfoce 最大长度,我认为使用Simple Validators 是实现此目的的最简单方法:

    class MyTable(Base):
        __tablename__ = 'my_table'
    
        id = Column(Integer, primary_key=True)
        code = Column(String(4))
        name = Column(String(10))
    
        @validates('code', '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:
                return value[:max_len]
            return value
    

    【讨论】:

    • 有没有办法让它适用于许多模型/表格?
    • @YaakovBressler:当然,只需将您想要的代码提取到基类或 mixin 类中。
    【解决方案2】:

    这是基于van's answer的通用解决方案:

    from sqlalchemy.orm import validates
    
    def TruncateString(*fields):
        class TruncateStringMixin:
            @validates(*fields)
            def validate_string_field_length(self, key, value):
                max_len = getattr(self.__class__, key).prop.columns[0].type.length
                if value and len(value) > max_len:
                    return value[:max_len]
                return value
    
        return TruncateStringMixin
    

    现在你可以使用它了

    class MyTable(Base, TruncateString('code', 'name')):
        __tablename__ = 'my_table'
    
        id = Column(Integer, primary_key=True)
        code = Column(String(4))
        name = Column(String(10))
    

    【讨论】:

      猜你喜欢
      • 2013-08-29
      • 1970-01-01
      • 2015-07-08
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      相关资源
      最近更新 更多