计算文本列作为其他两个列的 concat(字符串总和)

Computed text column as concat (sum of strings) of two other columns

我想要一个 table,其中我有一对独特的 sourcesource_id。但我还需要单列唯一 id 以使 API 更简单。

我正在尝试将 id 列作为其他两个列的连接:

from sqlalchemy import Computed, Column, Integer, Text
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Product(Base):
    __tablename__ = "product"

    id = Column(Text, Computed("source || source_id"), primary_key=True)
    source = Column(Text, nullable=False)
    source_id = Column(Integer, nullable=False)
    name = Column(Text, nullable=True)

我第一次尝试使用 contcat() 但它给了我错误:generation expression is not immutable.

它不能工作,我应该切换到 ||。但是 || 给了我同样的错误。如何解决?

下面是错误日志,其中包含生成的 SQL。

...
  File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 717, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.InvalidObjectDefinition) generation expression is not immutable

[SQL:
CREATE TABLE product (
        id TEXT GENERATED ALWAYS AS (source || source_id) STORED NOT NULL,
        source TEXT NOT NULL,
        source_id INTEGER NOT NULL,
        name TEXT,
        CONSTRAINT pk_product PRIMARY KEY (id)
)

]
(Background on this error at: https://sqlalche.me/e/14/f405)

怎么样

CREATE TABLE product(
    CONCAT (source, source_id) AS "TEXT GENERATED ALWAYS",
    ...
)

直接在您的 SQL 声明中?

明确地将 source_id 转换为 text 并且有效。

CREATE TABLE product
(
  id TEXT GENERATED ALWAYS AS (source || source_id::text) STORED NOT NULL,
  source TEXT NOT NULL,
  source_id INTEGER NOT NULL,
  name TEXT,
  CONSTRAINT pk_product PRIMARY KEY (id)
);

在 Python:

    id = Column(Text, Computed("source || source_id::text"), primary_key=True)

顺便说一句,id 不是多余的吗? CONSTRAINT pk_product PRIMARY KEY (source, source_id) 呢,即

    source = Column(Text, nullable=False, primary_key=True)
    source_id = Column(Integer, nullable=False, primary_key=True)