动态更改SQLAlchemy模型列类型

3 投票
1 回答
1956 浏览
提问于 2025-04-18 06:48

我遇到了一个问题 - 我在使用自定义的 JSON 类型来配合 PostgreSQL 数据库。
我需要同时使用 PostgreSQL 和 SQLite(在生产环境中用 PostgreSQL,在单元测试中用 SQLite 作为内存测试数据库)。

from sqlalchemy.dialects.postgresql.json import JSON


class Entity(ModelBase, SAModel):
   __tablename__ = 'entities'

  id = Column(pkey_type, primary_key=True, nullable=False)
  priority = Column(Integer, nullable=False)
  tags = Column(JSON, nullable=False, default={})

不幸的是,SQLite 不能直接处理 JSON。我需要一种类似于“SmartJSONType”的东西,它可以根据当前的 SQLAlchemy 方言来切换行为(在 PostgreSQL 中作为原生 JSON 类型工作,而在 SQLite 中作为字符串处理)。
有没有人能帮我解决这个问题?

1 个回答

2

你当然可以这样做。这里有一个完整的代码示例

不过,简单的例子是:

class JSONType(sa.types.TypeDecorator):
    impl = sa.UnicodeText

    def load_dialect_impl(self, dialect):
        if dialect.name == 'postgresql':
            return dialect.type_descriptor(JSON())
        else:
            return dialect.type_descriptor(self.impl)

    def process_bind_param(self, value, dialect):
        if dialect.name == 'postgresql':
            return value
        if value is not None:
            value = json.dumps(value)
        return value

   def process_result_value(self, value, dialect):
        if dialect.name == 'postgresql':
            return value
        if value is not None:
            value = json.loads(value)
        return value

我自己也是这样做的,因为我在内存中的sqlite数据库里跑快速测试,而在我们的实际生产数据库postgres里跑较慢的测试。

撰写回答