Lỗi trình tự TypeScript Upsert PostgreSQL: "Mối quan hệ 'customers_sq' không tồn tại"

Sequence

Hiểu các lỗi trình tự PostgreSQL trong Upserts

Làm việc với PostgreSQL và TypeScript, đặc biệt là trong quá trình thực hiện thao tác nâng cấp, đôi khi có thể dẫn đến các lỗi trình tự không mong muốn. Một lỗi phổ biến như vậy liên quan đến việc cơ sở dữ liệu không nhận dạng được trình tự, dẫn đến các thông báo như "quan hệ 'customers_sq' không tồn tại". Lỗi này thường xảy ra khi tham chiếu các chuỗi không chính xác trong các truy vấn SQL.

Trong bài viết này, chúng ta sẽ khám phá một tình huống thực tế trong đó nhà phát triển gặp phải sự cố này khi thực hiện nâng cấp. Chúng ta sẽ thảo luận về cách các chuỗi hoạt động trong PostgreSQL và xác định các lỗi phổ biến khi tham chiếu chúng, đặc biệt là trong TypeScript.

Thông thường, những lỗi này phát sinh do cú pháp hoặc phạm vi lược đồ không chính xác, đặc biệt là khi xử lý các chuỗi trong các lược đồ cơ sở dữ liệu hoặc không gian tên khác nhau. Việc gỡ lỗi vấn đề đòi hỏi phải chú ý cẩn thận đến cách PostgreSQL mong đợi các chuỗi được tham chiếu trong truy vấn.

Đến cuối hướng dẫn này, bạn sẽ hiểu rõ hơn lý do tại sao lỗi "mối quan hệ không tồn tại" này xảy ra và các bước bạn có thể thực hiện để khắc phục lỗi đó. Điều này bao gồm các mẹo thực tế để giải quyết các vấn đề về tham chiếu trình tự và đảm bảo các phần bổ sung của bạn hoạt động như dự định trong PostgreSQL.

Yêu cầu Ví dụ về sử dụng
NEXTVAL('sequence_name') Hàm PostgreSQL này truy xuất giá trị tiếp theo từ một chuỗi được chỉ định. Điều quan trọng là tạo ID duy nhất cho các hàng trong quá trình chèn. Ví dụ: NEXTVAL('db.customers_sq') lấy giá trị tiếp theo từ trình tự trong lược đồ "db".
ON CONFLICT ("column") DO UPDATE Được sử dụng trong các hoạt động nâng cấp PostgreSQL, lệnh này xử lý các trường hợp việc chèn sẽ dẫn đến xung đột trên một cột duy nhất. Thay vì thất bại, nó cập nhật hàng xung đột. Ví dụ: KHI XUNG ĐỘT ("id") THIẾT LẬP CẬP NHẬT "name" = $1.
pg_sequences Chế độ xem danh mục PostgreSQL cung cấp thông tin về tất cả các chuỗi trong cơ sở dữ liệu. Điều này được sử dụng để truy vấn siêu dữ liệu về các chuỗi, chẳng hạn như sự tồn tại của chúng trong một lược đồ cụ thể. Ví dụ: CHỌN * TỪ pg_sequences WHERE Sequencename = 'customers_sq';
pool.query() Một phương thức từ mô-đun nút PostgreSQL , được sử dụng để thực thi các truy vấn SQL. Nó xử lý các kết nối cơ sở dữ liệu một cách hiệu quả, gộp chúng lại để tái sử dụng. Ví dụ: pool.query(SAVE_CUSTOMER, [name]) thực thi SQL chèn/cập nhật cho khách hàng.
mockResolvedValueOnce() Một phương pháp Jest được sử dụng trong thử nghiệm. Nó mô phỏng phản hồi của hàm để trả về một giá trị cụ thể một lần. Trong trường hợp này, nó mô phỏng việc thực hiện thành công một truy vấn cơ sở dữ liệu. Ví dụ: pool.query.mockResolvedValueOnce({}).
mockRejectedValueOnce() Hàm Jest này mô phỏng một lỗi do một lời hứa đưa ra, mô phỏng một truy vấn không thành công. Ví dụ: pool.query.mockRejectedValueOnce(new Error('Sequence not Found')) lặp lại lỗi trong đó thiếu một chuỗi.
expect.toThrow() Một xác nhận Jest xác minh xem một hàm có đưa ra một lỗi được chỉ định hay không. Điều này rất cần thiết để kiểm tra cách hoạt động của chức năng khi xảy ra lỗi. Ví dụ: mong đợi(saveCustomer('John')).rejects.toThrow('Không tìm thấy chuỗi');.
schemaname Một cột trong chỉ ra lược đồ nơi trình tự được xác định. Nó giúp phân biệt giữa các chuỗi có cùng tên nhưng ở các lược đồ khác nhau. Ví dụ: CHỌN * TỪ pg_sequences WHERE lược đồ = 'db';.

Cách xử lý lỗi trình tự PostgreSQL trong Upserts

Các tập lệnh được cung cấp trong các ví dụ trước đó được thiết kế để giải quyết một vấn đề phổ biến phát sinh khi tham chiếu các chuỗi trong PostgreSQL, đặc biệt là trong quá trình hoạt động trong TypeScript. Thao tác upsert sẽ chèn các bản ghi mới hoặc cập nhật các bản ghi hiện có, khiến việc sử dụng đúng các chuỗi trở nên quan trọng để duy trì các khóa chính duy nhất. Vấn đề chính ở đây xuất phát từ việc tham chiếu trình tự không chính xác, dẫn đến lỗi: "relation '

Tập lệnh đầu tiên giải quyết vấn đề này bằng cách đảm bảo rằng trình tự được tham chiếu chính xác với nhận thức về lược đồ. Khi chúng tôi sử dụng , chúng tôi chỉ định cả lược đồ ("db") và trình tự ("customers_sq"), đảm bảo rằng PostgreSQL tìm kiếm trình tự trong ngữ cảnh chính xác. Nếu lược đồ bị bỏ qua hoặc được tham chiếu không đúng cách, PostgreSQL có thể không tìm thấy trình tự, gây ra lỗi. Lệnh này hoạt động trong một trong TypeScript, đảm bảo rằng đầu vào của người dùng được chuyển vào truy vấn một cách an toàn để ngăn chặn các cuộc tấn công tiêm nhiễm SQL.

Ngoài ra, một giải pháp thay thế được cung cấp bằng cách sử dụng kiểm tra trình tự động. Cách tiếp cận này truy vấn chế độ xem danh mục PostgreSQL, , để xác minh sự tồn tại của chuỗi trước khi thử chèn hoặc cập nhật bản ghi. Điều này không chỉ bổ sung thêm một lớp xử lý lỗi mà còn đảm bảo rằng tập lệnh linh hoạt và mạnh mẽ, có khả năng thích ứng với những thay đổi trong lược đồ cơ sở dữ liệu. Bằng cách kiểm tra trình tự một cách linh hoạt, hệ thống có thể cung cấp thông báo lỗi nhiều thông tin hơn nếu trình tự bị thiếu hoặc được tham chiếu không chính xác, cải thiện quá trình gỡ lỗi.

Cuối cùng, kiểm tra đơn vị là một phần thiết yếu của giải pháp. các bộ kiểm tra được sử dụng để đảm bảo rằng hàm upsert hoạt động như mong đợi. Trong các thử nghiệm, cả các thao tác thành công và các trường hợp lỗi, chẳng hạn như trình tự bị thiếu, đều được xử lý. Các trường hợp thử nghiệm sử dụng các phương pháp như Và để mô phỏng cách cơ sở dữ liệu phản hồi các truy vấn. Bằng cách xác minh rằng các lệnh SQL chính xác được thực thi và các lỗi được đưa ra một cách thích hợp khi thiếu trình tự, các trường hợp kiểm thử sẽ giúp đảm bảo độ tin cậy của giải pháp trên các môi trường khác nhau.

Giải quyết lỗi tham chiếu trình tự PostgreSQL trong Upsert

Giải pháp này giải quyết vấn đề quản lý cơ sở dữ liệu liên quan đến PostgreSQL và TypeScript. Tập lệnh sử dụng các truy vấn được tham số hóa và tối ưu hóa việc tham chiếu trình tự với nhận thức về lược đồ.

// TypeScript - Upsert solution using parameterized query with correct sequence reference
import { Pool } from 'pg';
const pool = new Pool();
const SAVE_CUSTOMER = `
  INSERT INTO "db"."customers" ("id", "name")
  VALUES (NEXTVAL('db.customers_sq'), $1)
  ON CONFLICT ("id") DO UPDATE SET "name" = $1`;
async function saveCustomer(name: string) {
  try {
    await pool.query(SAVE_CUSTOMER, [name]);
    console.log('Customer saved successfully');
  } catch (error) {
    console.error('Error saving customer:', error.message);
  }
}

Phương pháp thay thế: Tham chiếu trình tự động với kiểm tra lược đồ

Tập lệnh này tự động kiểm tra lược đồ và tham chiếu trình tự chính xác, đảm bảo tính linh hoạt trong môi trường PostgreSQL nơi các lược đồ có thể khác nhau.

// TypeScript - Dynamic sequence referencing with schema awareness
import { Pool } from 'pg';
const pool = new Pool();
async function saveCustomer(name: string) {
  try {
    const checkSequence = `SELECT EXISTS (
      SELECT 1 FROM pg_sequences WHERE schemaname = 'db' AND sequencename = 'customers_sq');`;
    const sequenceExists = await pool.query(checkSequence);
    if (!sequenceExists.rows[0].exists) {
      throw new Error('Sequence not found');
    }
    const SAVE_CUSTOMER = `
      INSERT INTO "db"."customers" ("id", "name")
      VALUES (NEXTVAL('db.customers_sq'), $1)
      ON CONFLICT ("id") DO UPDATE SET "name" = $1`;
    await pool.query(SAVE_CUSTOMER, [name]);
    console.log('Customer saved successfully');
  } catch (error) {
    console.error('Error saving customer:', error.message);
  }
}

Kiểm thử đơn vị cho việc nâng cấp trình tự PostgreSQL

Kiểm thử đơn vị này đảm bảo rằng hàm upsert xử lý các lỗi trình tự và chèn hoặc cập nhật thành công các bản ghi trong PostgreSQL.

// Jest - Unit test for saveCustomer function
import { saveCustomer } from './saveCustomer';
import { pool } from 'pg';
jest.mock('pg');
describe('saveCustomer', () => {
  it('should insert new customer if no conflict', async () => {
    pool.query.mockResolvedValueOnce({});
    await saveCustomer('John Doe');
    expect(pool.query).toHaveBeenCalledWith(expect.any(String), ['John Doe']);
  });
  it('should throw error if sequence does not exist', async () => {
    pool.query.mockRejectedValueOnce(new Error('Sequence not found'));
    await expect(saveCustomer('John Doe')).rejects.toThrow('Sequence not found');
  });
});

Các yếu tố chính đằng sau lỗi trình tự PostgreSQL

Một khía cạnh chưa được đề cập trước đây là cách PostgreSQL xử lý khi nói đến các đối tượng cơ sở dữ liệu như trình tự. PostgreSQL mặc định coi các mã định danh không được trích dẫn là chữ thường. Điều này có nghĩa là nếu tên chuỗi được tạo bằng chữ in hoa nhưng được tham chiếu không có dấu ngoặc kép thì PostgreSQL sẽ tự động tìm kiếm phiên bản chữ thường. Ví dụ: nếu chuỗi được tạo là "Customers_SQ" nhưng được tham chiếu là , có thể dẫn đến lỗi "quan hệ không tồn tại". Sử dụng dấu ngoặc kép xung quanh tên trình tự, chẳng hạn như , đảm bảo PostgreSQL sử dụng trường hợp chính xác như được xác định.

Một khía cạnh quan trọng khác là khả năng hiển thị lược đồ trong PostgreSQL. Theo mặc định, PostgreSQL tìm kiếm các chuỗi trong lược đồ đầu tiên trong đường dẫn tìm kiếm trừ khi lược đồ được xác định rõ ràng. Nếu trình tự nằm trong một lược đồ khác thì việc tham chiếu đến nó mà không chỉ định lược đồ đó (ví dụ: ) có thể dẫn đến lỗi không tìm thấy chuỗi. Các nhà phát triển cần điều chỉnh đường dẫn tìm kiếm hoặc tham chiếu lược đồ một cách rõ ràng để tránh sự cố này, đặc biệt là trong các cấu trúc cơ sở dữ liệu phức tạp có nhiều lược đồ.

Cuối cùng, điều quan trọng là phải đề cập đến cơ sở dữ liệu . Nếu người dùng không có các đặc quyền cần thiết để truy cập hoặc sửa đổi trình tự, họ có thể gặp phải các lỗi như "quan hệ không tồn tại". Việc cấp quyền chính xác cho các vai trò tương tác với chuỗi cơ sở dữ liệu sẽ đảm bảo chúng có thể truy xuất giá trị tiếp theo thông qua không có vấn đề. Điều này đặc biệt quan trọng trong môi trường sản xuất có kiểm soát truy cập nghiêm ngặt và nhiều vai trò tương tác với cơ sở dữ liệu.

  1. Lỗi "quan hệ không tồn tại" có nghĩa là gì trong PostgreSQL?
  2. Lỗi này thường có nghĩa là PostgreSQL không thể tìm thấy trình tự hoặc bảng mà bạn đang tham chiếu, thường là do đặt tên trình tự, khả năng hiển thị lược đồ hoặc phân biệt chữ hoa chữ thường không chính xác.
  3. Làm cách nào tôi có thể khắc phục các vấn đề về phân biệt chữ hoa chữ thường trong các tham chiếu trình tự PostgreSQL?
  4. Sử dụng dấu ngoặc kép xung quanh tên trình tự như để đảm bảo PostgreSQL sử dụng đúng kiểu chữ như được xác định trong quá trình tạo.
  5. Vai trò của lược đồ trong các lỗi trình tự là gì?
  6. Nếu một chuỗi không có trong lược đồ mặc định, bạn phải tham chiếu rõ ràng lược đồ trong lệnh của mình, chẳng hạn như .
  7. Làm cách nào để kiểm tra xem một chuỗi có tồn tại trong PostgreSQL không?
  8. Bạn có thể truy vấn bảng để xác minh sự tồn tại của một chuỗi. Ví dụ:
  9. Tôi nên làm gì nếu không có quyền truy cập vào một trình tự?
  10. Đảm bảo vai trò người dùng có các đặc quyền thích hợp. Bạn có thể cấp quyền truy cập bằng lệnh .

Để giải quyết lỗi "quan hệ 'customers_sq' không tồn tại", hãy đảm bảo tham chiếu đúng lược đồ và tên chuỗi khớp với quy tắc phân biệt chữ hoa chữ thường của PostgreSQL. Kiểm tra kỹ các quyền của trình tự để tránh các sự cố truy cập trong quá trình thực hiện các thao tác nâng cấp.

Luôn sử dụng cẩn thận và xác minh rằng trình tự tồn tại trong cơ sở dữ liệu PostgreSQL của bạn bằng cách truy vấn danh mục. Thực hiện theo các bước gỡ lỗi này sẽ đảm bảo rằng hoạt động cơ sở dữ liệu của bạn chạy trơn tru và hiệu quả mà không có lỗi liên quan đến trình tự.

  1. Xây dựng tài liệu PostgreSQL liên quan đến và xử lý lỗi trong truy vấn: Tài liệu chính thức của PostgreSQL .
  2. Chi tiết về cách sử dụng và quản lý lược đồ trong PostgreSQL để tham chiếu trình tự thích hợp: Các hàm và toán tử PostgreSQL .
  3. Khám phá chuyên sâu về vấn đề nâng cao và giải quyết xung đột với trong PostgreSQL: Lệnh INSERT PostgreSQL .
  4. Thông tin về các thông báo lỗi PostgreSQL phổ biến và kỹ thuật gỡ lỗi: Mã lỗi PostgreSQL .
  5. Thảo luận về tích hợp với PostgreSQL, tập trung vào xử lý lỗi và tương tác với cơ sở dữ liệu: Tài liệu về Node-Postgres (trang) .