Node.js 如何在列更改数据库中的名称时扩展或更新冲突解决程序以允许向后兼容

Node.js 如何在列更改数据库中的名称时扩展或更新冲突解决程序以允许向后兼容,node.js,postgresql,graphql,apollo,Node.js,Postgresql,Graphql,Apollo,我正在处理一个包含Node、GraphQL和PostgreSQL的项目。 在这种情况下,我的数据库中有一列需要更改为新名称,因为范围从contact更改为contact\u hours 我的问题是我必须保持向后兼容性,这意味着我一直在使用preferredContact,新字段是preferredContactHours。为避免错过服务,我们需要确保每当有人使用preferredContact时,它会点击preferredContactHours,因此数据将始终显示 我在DB中进行了更改,并在G

我正在处理一个包含Node、GraphQL和PostgreSQL的项目。 在这种情况下,我的数据库中有一列需要更改为新名称,因为范围从
contact
更改为
contact\u hours

我的问题是我必须保持向后兼容性,这意味着我一直在使用
preferredContact
,新字段是
preferredContactHours
。为避免错过服务,我们需要确保每当有人使用
preferredContact
时,它会点击
preferredContactHours
,因此数据将始终显示

我在DB中进行了更改,并在GQL文件中进行了类型克隆,如下所示:

type Candidate {
  id: ID!
  name: String
  contacts: [Contact]
  "Deprecated: Use the new preferredContactHours"
  preferredContact: String 
  "New naming: The hours the candidate prefers to be contacted"
  preferredContactHours: String
  }
Candidate: {
    comments(candidate, _, ctx) {
      return CommentService(ctx).getComments({
        filter: { candidateId: candidate.id },
      });
    },

    status(candidate, args, ctx) {
      return StatusService(ctx).getCandidateStatus(candidate.id);
    },
    activities(candidate, args, ctx) {
      return CandidateActivityService(ctx).getActivity({
        id: candidate.id,
        actions: args.actions,
      });
    },
    contacts(candidate, args, ctx) {
      return ContactService(ctx).getContacts({
        filter: {
          candidateId: candidate.id,
        },
      });
    },
    nextCall(candidate, args, ctx) {
      return ScheduleService(ctx).getNextSchedule({
        candidateId: candidate.id,
        type: 'CALL',
      });
    },
    nextVisit(candidate, args, ctx) {
      return ScheduleService(ctx).getNextSchedule({
        candidateId: candidate.id,
        type: 'VISIT',
      });
    },
    allowedStatusChanges(candidate, args, ctx) {
      return StatusService(ctx).getAllowedStatusChanges({
        id: candidate.id,
        rule: 'allowed',
      });
    },
    rejectionStatus(candidate, args, ctx) {
      return StatusService(ctx).getAllowedStatusChanges({
        id: candidate.id,
        rule: 'rejection',
      });
    },
    notes(candidate, args, ctx) {
      return NoteService(ctx).getNotes({
        candidateId: candidate.id,
        questionnaireId: args.questionnaireId,
      });
    },
    allowedActions(candidate, args, ctx) {
      return StatusService(ctx)
        .getCandidateStatus(candidate.id)
        .then(status => statusAllowedActions[status.type]);
    },
  },
在我的resolver.js中,我在一个变异脚本下做了如下操作:

setCandidateContactDetails(
      _,
      {
        input: {
          candidateId,
          // Deprecated: Use the new preferredContactHours
          preferredContact,
          // New naming: The hours the candidate prefers to be contacted
          preferredContactHours,
          ...
      },
      ctx
    ) {
      return CandidateService(ctx).updateCandidate({
        candidate: {
          id: candidateId,
          // Deprecated: Use the new preferredContactHours
          preferredContact,
          // New naming: The hours the candidate prefers to be contacted
          preferredContactHours,
          ...
      });
现在,我需要在候选变量的内部进行更改,以确保在实际使用
preferredContact
时过滤
preferredContactHours

这一部分我有一个问题,因为我是GraphQL新手,不知道如何实现它。 我现在发现的具体突变如下:

type Candidate {
  id: ID!
  name: String
  contacts: [Contact]
  "Deprecated: Use the new preferredContactHours"
  preferredContact: String 
  "New naming: The hours the candidate prefers to be contacted"
  preferredContactHours: String
  }
Candidate: {
    comments(candidate, _, ctx) {
      return CommentService(ctx).getComments({
        filter: { candidateId: candidate.id },
      });
    },

    status(candidate, args, ctx) {
      return StatusService(ctx).getCandidateStatus(candidate.id);
    },
    activities(candidate, args, ctx) {
      return CandidateActivityService(ctx).getActivity({
        id: candidate.id,
        actions: args.actions,
      });
    },
    contacts(candidate, args, ctx) {
      return ContactService(ctx).getContacts({
        filter: {
          candidateId: candidate.id,
        },
      });
    },
    nextCall(candidate, args, ctx) {
      return ScheduleService(ctx).getNextSchedule({
        candidateId: candidate.id,
        type: 'CALL',
      });
    },
    nextVisit(candidate, args, ctx) {
      return ScheduleService(ctx).getNextSchedule({
        candidateId: candidate.id,
        type: 'VISIT',
      });
    },
    allowedStatusChanges(candidate, args, ctx) {
      return StatusService(ctx).getAllowedStatusChanges({
        id: candidate.id,
        rule: 'allowed',
      });
    },
    rejectionStatus(candidate, args, ctx) {
      return StatusService(ctx).getAllowedStatusChanges({
        id: candidate.id,
        rule: 'rejection',
      });
    },
    notes(candidate, args, ctx) {
      return NoteService(ctx).getNotes({
        candidateId: candidate.id,
        questionnaireId: args.questionnaireId,
      });
    },
    allowedActions(candidate, args, ctx) {
      return StatusService(ctx)
        .getCandidateStatus(candidate.id)
        .then(status => statusAllowedActions[status.type]);
    },
  },
我得到一个建议,在上面的代码片段中添加一个新条目作为示例

contactsHours(candidate) {
      return ContactService().getContacts({
        <Something here ???>
      });
    },
    Query
     {
      candidate(id: "000") {
        name
        preferredContact
      }
    }
result
"data": {
    "candidate": {
      "name": "xxxx",
      "preferredContactHours": "8-12",
    }
  },
我也可以在上面的查询中用
preferredContactHours
替换,并具有相同的数据结果


如果需要更多的解释或代码,请用我将更新帖子的请求进行评论,以便更好地理解。

“弃用”表示仍然有效,新选项与现有选项并行工作,保留所有功能

  • 查询这两个值应该是有效的
  • 两者应分开工作,包括过滤
  • 您可以在写入时将旧输入值复制到新输入值(如果未提供新输入值)
  • 如果没有值(旧记录),您可以读取/提供旧DB字段值作为新字段的结果

返回
preferredContactHours
而不是查询的
preferredContact
在graphql中无效
-服务器不应以这种方式工作,它必须返回所有查询属性的值。

如果运行Postgres 12,则有一个解决方法。Postgres 12提供生成的列,因此您可以将新列名基本上作为“别名”添加到现有列中。基本上

alter table ta add column 
      preferredContactHours {datatype} 
      generated always as (preferredContact) stored;
其中{datayype}对应于preferredContact的数据类型。现在,您可以通过任意名称访问数据值。在发布本文件的同时,您的发行说明应注明:

“preferredContact已被弃用,优先于preferredContactHours,并将在发行号或日期中删除。届时,任何未更新以访问preferredContactHours的应用程序都将失败。”


在模糊处理层(节点、GraphQL等)中如何处理这个问题?对不起,我不知道。祝你好运。

好的,你不能更新你的答案,为我的情况提供一个可能的解决方案,这将是一个伟大的获得更多关于它的问题,今天没有时间了。。。在传递到DB/service之前添加一些条件/准备参数/输入值,或者在从解析器返回之前更新从DB/service获取的数据。。。您还可以尝试更新服务/中间件中的写入/读取数据(几乎不涉及解析器)。。。取决于实施细节