SQLAlchemy监听after_create事件报错,如何为Test表添加约束?
解决SQLAlchemy中
after_create事件无效的问题 你遇到的InvalidRequestError原因很明确:SQLAlchemy的after_create事件是针对数据库表对象(Table实例)的,而非你直接绑定的ORM模型类Test。下面给你几种可行的解决办法:
方法1:修正事件绑定的目标
把事件监听的目标从Test改成Test.__table__(模型类对应的表对象),修改后的代码如下:
from sqlalchemy import Column, INTEGER, VARCHAR, DDL from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import event Base = declarative_base() class Test(Base): __tablename__ = 'test' id = Column('id', INTEGER, primary_key=True) name = Column('name', VARCHAR(30)) progress = Column('progress', VARCHAR(4), server_default='0') # 绑定到表对象而非模型类 event.listen( Test.__table__, "after_create", DDL("ALTER TABLE test ADD CONSTRAINT " "cst_test_progress " " CHECK (progress like '[0-9]')") )
方法2:用ORM原生方式定义CHECK约束(更推荐)
其实不需要手动写DDL和监听事件,SQLAlchemy提供了更简洁的方式直接在模型中定义约束,维护起来更方便:
方式A:通过Column的check_constraint参数
progress = Column('progress', VARCHAR(4), server_default='0', check_constraint="progress like '[0-9]'")
方式B:用CheckConstraint对象(支持命名约束)
from sqlalchemy import CheckConstraint class Test(Base): __tablename__ = 'test' id = Column('id', INTEGER, primary_key=True) name = Column('name', VARCHAR(30)) progress = Column('progress', VARCHAR(4), server_default='0') # 定义表级约束,指定约束名称 __table_args__ = ( CheckConstraint('progress like \'[0-9]\'', name='cst_test_progress'), )
额外提醒:注意数据库的模式匹配语法
你写的progress like '[0-9]'并不是所有数据库都支持:
- MySQL:不支持用
like匹配范围,需要改成progress REGEXP '^[0-9]$' - PostgreSQL:可以用
progress ~ '^[0-9]$'或者progress SIMILAR TO '[0-9]' - SQLite:用
progress GLOB '[0-9]'(如果需要正则匹配,还要额外启用扩展)
根据你使用的数据库调整约束条件,才能保证约束真正生效。
内容的提问来源于stack exchange,提问作者Nikolay Shevchenko
相关产品推荐
相关产品推荐

