0
0
Lập trình
Admin Team
Admin Teamtechmely

Khắc phục lỗi Doctrine: Cập nhật schema không thay đổi SQL

Đăng vào 8 tháng trước

• 4 phút đọc

Giới thiệu

Trong quá trình triển khai một ứng dụng, việc quản lý cơ sở dữ liệu là rất quan trọng. Đặc biệt, khi sử dụng Doctrine ORM trong Symfony, bạn có thể gặp phải tình huống mà lệnh doctrine:schema:update vẫn xuất ra các câu lệnh SQL mặc dù đã có những thay đổi được áp dụng lên cơ sở dữ liệu. Bài viết này sẽ giúp bạn hiểu rõ nguyên nhân và cách khắc phục vấn đề này.

Vấn đề gặp phải

Khi triển khai ứng dụng, nhóm của tôi thường sử dụng phương pháp so sánh (diffs) thay vì sử dụng migration để cập nhật cơ sở dữ liệu. Khi chạy lệnh sau:

bash Copy
$ php bin/console doctrine:schema:update --dump-sql 

Tôi nhận được khoảng 93 câu lệnh SQL cần áp dụng lên cơ sở dữ liệu:

sql Copy
ALTER TABLE xxx1 CHANGE expires_at expires_at DATETIME DEFAULT NULL;
ALTER TABLE xx2 CHANGE name name VARCHAR(255) DEFAULT NULL;
ALTER TABLE xx3 CHANGE description description VARCHAR(255) DEFAULT NULL;

Sau đó, tôi đã thử áp dụng các thay đổi bằng lệnh:

bash Copy
$ php bin/console doctrine:schema:update --force

Và khi kiểm tra lại bằng lệnh --dump-sql, tôi vẫn thấy xuất ra các câu lệnh SQL giống hệt như trước:

sql Copy
ALTER TABLE xxx1 CHANGE expires_at expires_at DATETIME DEFAULT NULL;
ALTER TABLE xx2 CHANGE name name VARCHAR(255) DEFAULT NULL;
ALTER TABLE xx3 CHANGE description description VARCHAR(255) DEFAULT NULL;

Điều này thật khó hiểu vì tôi đã áp dụng các thay đổi.

Nguyên nhân

Để tìm hiểu nguyên nhân, tôi đã hỏi ý kiến một đồng nghiệp. Anh ấy đã thử tạo một migration như sau:

bash Copy
php bin/console doctrine:migrations:diff

Tuy nhiên, điều này dẫn đến lỗi sau:

Copy
The metadata storage is not up to date, please run the sync-metadata-storage command to fix this issue.

Nguyên nhân của vấn đề này là cả hai lệnh doctrine:migrations:diffdoctrine:schema:update đều sử dụng cùng một logic để so sánh các thay đổi. Tuy nhiên, việc tạo migration cũng sẽ phát hiện ra bất kỳ lỗi nào.

Cấu hình sai phiên bản MariaDB

Trong file .env, tôi đã cấu hình như sau:

Copy
DATABASE_URL=mysql://xxx:yyy@127.0.0.1:3306/testtest?serverVersion=10.4

Như bạn thấy, chúng tôi đang sử dụng MariaDB và thông tin serverVersion bao gồm phiên bản MariaDB. Giải pháp là lấy phiên bản chính xác (bao gồm cả phiên bản phụ) bằng lệnh:

bash Copy
mysql --version

Sau đó, cấu hình lại serverVersion trong biến môi trường:

Copy
database_url=mysql://xxx:yyy@127.0.0.1:3306/testtest?serverVersion=mariadb-10.4.1

Tuy nhiên, lựa chọn mà chúng tôi đã chọn là bỏ hoàn toàn đối số serverVersion trong DATABASE_URL, điều này đã khắc phục được vấn đề.

Giải pháp chi tiết

Để khắc phục vấn đề trên, bạn có thể thực hiện theo các bước sau:

  1. Kiểm tra phiên bản MariaDB:

    • Sử dụng lệnh mysql --version để kiểm tra phiên bản hiện tại của MariaDB.
  2. Cập nhật file cấu hình .env:

    • Cập nhật hoặc bỏ phần serverVersion trong chuỗi kết nối cơ sở dữ liệu của bạn.
    • Ví dụ:
    Copy
    DATABASE_URL=mysql://username:password@127.0.0.1:3306/dbname
  3. Chạy lệnh đồng bộ hóa metadata:

    • Nếu bạn cần sử dụng doctrine:migrations:diff, hãy chạy lệnh sau để đồng bộ hóa metadata:
    bash Copy
    php bin/console doctrine:migrations:sync-metadata-storage
  4. Chạy lại lệnh cập nhật schema:

    • Bây giờ bạn có thể chạy lại lệnh cập nhật schema:
    bash Copy
    php bin/console doctrine:schema:update --force
  5. Kiểm tra lại các thay đổi:

    • Cuối cùng, kiểm tra lại bằng lệnh --dump-sql để đảm bảo rằng không có thay đổi nào còn thiếu.
    bash Copy
    php bin/console doctrine:schema:update --dump-sql

Mẹo tốt nhất

  • Lưu trữ bản sao lưu: Trước khi thực hiện bất kỳ thay đổi nào trên cơ sở dữ liệu, hãy luôn sao lưu dữ liệu để tránh mất mát.
  • Sử dụng migration: Nếu có thể, hãy sử dụng migration thay vì cập nhật trực tiếp schema để dễ dàng theo dõi các thay đổi.
  • Kiểm tra trạng thái metadata: Thường xuyên kiểm tra và đồng bộ hóa trạng thái metadata của Doctrine để tránh các lỗi tương tự trong tương lai.

Các cạm bẫy thường gặp

  • Bỏ qua cập nhật phiên bản: Nhiều nhà phát triển không chú ý đến thông tin phiên bản trong cấu hình cơ sở dữ liệu, dẫn đến các lỗi không mong muốn.
  • Không kiểm tra lại sau khi cập nhật: Sau khi thực hiện cập nhật, cần kiểm tra kỹ lưỡng để đảm bảo rằng mọi thứ hoạt động như mong đợi.

Câu hỏi thường gặp (FAQ)

1. Tại sao tôi vẫn thấy các câu lệnh SQL giống nhau sau khi đã áp dụng?

  • Điều này thường xảy ra do phiên bản MariaDB không chính xác trong cấu hình hoặc metadata không được đồng bộ hóa.

2. Làm thế nào để biết phiên bản MariaDB tôi đang sử dụng?

  • Bạn có thể sử dụng lệnh mysql --version trong terminal để kiểm tra phiên bản hiện tại.

3. Có cách nào dễ dàng hơn để quản lý các thay đổi trong cơ sở dữ liệu không?

  • Sử dụng Doctrine Migrations để theo dõi và quản lý các thay đổi một cách hiệu quả hơn.

Kết luận

Việc quản lý cơ sở dữ liệu có thể trở nên phức tạp, nhưng với các bước và giải pháp đúng đắn, bạn có thể dễ dàng khắc phục các vấn đề thường gặp. Hãy đảm bảo rằng bạn luôn kiểm tra phiên bản và trạng thái của Doctrine để tránh những rắc rối không cần thiết. Nếu bài viết này hữu ích đối với bạn, hãy chia sẻ với đồng nghiệp và tiếp tục theo dõi các bài viết tiếp theo của chúng tôi để cập nhật thêm nhiều kiến thức mới mẻ trong lĩnh vực phát triển phần mềm!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào