SQLAlchemy自定义数据类型

快来打我* 2021-10-28 20:14 531阅读 0赞

有时,我们想把一个dict对象存到MySQL表里面,由于MySQL没有定义dict之类的数据类型,一种做法是,每当往表里写入数据时,先将dict对象转换成字符串形式,每当从表里读取数据时,将读出来的字符串转换成dict对象。如果应用开发者自己显式地处理数据转换,显得麻烦并且较易出错。

SQLAlchemy允许自定义数据类型来扩展已有数据类型。为了定义新的数据类型,需要继承TypeDecorator类,并且定义bind-parameter和result-processing行为。bind-parameter行为决定在写入数据库时如何转换数据,result-processing行为决定在读取数据库时如何转换数据。

了解MongoDB的人一定知道ObjectId,它是MongoDB文档的Id。假设我们需要将ObjectId存到MySQL里面,而MySQL没有类似ObjectId的数据类型,我们定义一个新的数据类型。由于ObjectId有其二进制和字符串形式的表示,我们将要自定义的数据类型可以在已有MySQL数据类型BINARY或者VARCHAR的基础上扩展。下面以BINARY作为示例。

  1. import sqlalchemy.types as types
  2. from bson import ObjectId
  3. class MysqlObjectId(types.TypeDecorator):
  4. """ custom type
  5. Usage:
  6. MysqlObjectId(12)
  7. ObjectId's binary representation has 12 bytes.
  8. """
  9. impl = types.BINARY
  10. def process_bind_param(self, value, dialect):
  11. """define bind-parameter behavior
  12. """
  13. if value is not None:
  14. try:
  15. # when value is not None,
  16. # ObjectId's __init__ method will validate if value is illegal
  17. # return the binary representation) of ObjectId
  18. return ObjectId(value).binary
  19. except:
  20. pass
  21. return None
  22. def process_result_value(self, value, dialect):
  23. """define result-processing behavior
  24. """
  25. if value is not None:
  26. try:
  27. return ObjectId(value)
  28. except:
  29. pass
  30. return None

上面定义了MysqlObjectId类型,下面的代码示例了如何使用该自定义类型。

  1. import sqlalchemy as SA
  2. from sqlalchemy.ext.declarative import declarative_base
  3. Base = declarative_base()
  4. class TestTable(Base):
  5. __tablename__ = "test_table"
  6. # column definitions
  7. id = SA.Column(SA.Integer, primary_key=True, autoincrement=True)
  8. object_id = SA.Column(MysqlObjectId(12), nullable=True)

测试代码就不写了。

发表评论

表情:
评论列表 (有 0 条评论,531人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SQLAlchemy定义数据类型

    有时,我们想把一个dict对象存到MySQL表里面,由于MySQL没有定义dict之类的数据类型,一种做法是,每当往表里写入数据时,先将dict对象转换成字符串形式,每当从表里