【问题标题】:Change SQLAlchemy model column type on-the-fly即时更改 SQLAlchemy 模型列类型
【发布时间】:2014-07-05 10:44:37
【问题描述】:

我有一个问题 - 我为 postgresql 方言使用自定义 JSON 类型。 我需要同时使用 postgres/sqlite(用于生产的 postgres,用于单元测试的 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 方言切换行为(使用 JSON 作为 SQLite 中的原生 Postgres JSON 数据类型和字符串)。
谁能帮我解决这个问题?

【问题讨论】:

  • 那么您是否需要帮助来模拟 JSON 方言的行为,仅使用 String 列和 SQLite,或者在两种实现之间进行切换,或两者兼而有之?
  • 你确定要那个吗?在 postgresql 中使用 json 的主要好处是它为在查询中使用 json 值提供了丰富的运算符集。你不会在 sqlite 中得到任何这些;只是不相关且不太有用的字符串运算符(反过来,在 postgresql JSON 类型上不可用)。如果您的唯一目的是存储 json 数据,请在任何地方使用String
  • 哦,我知道这是一个非常古老的问题,但是因为我遇到它试图找到答案,所以我想我应该回来并回答它的完整性:)

标签: python json sqlite postgresql sqlalchemy


【解决方案1】:

您当然可以这样做。有一个complete code example here

但简化的例子是:

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)中运行较慢的测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    • 2015-08-31
    相关资源
    最近更新 更多