Tóm tắt / TL; DR
Trong 3 bước, bạn sẽ có thể thực hiện rất đơn giản:
INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name -- backup_db being remote
Đầu tiên cài đặt bản sao lưu cục bộ, thứ hai tải tập lệnh SQL, thứ ba mở localhost của bạn ra thế giới bên ngoài bằng ngrok .
Đi thôi?
1. Tải xuống tệp kết xuất của bạn trên Heroku và đổ nó ở đâu đó:
- Bạn có thể làm điều đó trên cơ sở dữ liệu từ xa nếu bạn có sẵn một số máy chủ. Nhưng nếu giống như tôi, bạn không muốn cung cấp một cơ sở dữ liệu sản xuất khác trên Heroku hoặc một nơi nào khác, thì địa phương sẽ hoàn toàn làm được.
- Tôi thích sử dụng PGAdmin
(khả dụng trên Linux, Mac và Windows), nhưng sử dụng dòng lệnh và
psql
cũng sẽ làm được (bằng cách đọc đăng bài bằng ví dụ) - Trong PGAdmin, bạn sẽ thực hiện
Create a database
. Sau đó nhấp chuột phải vào nó và sử dụngrestore
hàm số. Chọn tệp kết xuất của bạn, nhấp vàoRestore
và bạn đã sẵn sàng: dữ liệu sao lưu của bạn có sẵn cục bộ! Làm tốt lắm!
2. Truy cập nó từ cơ sở dữ liệu từ xa của bạn
Tôi muốn làm như sau:
SELECT * FROM backup_db.table_name
-- So I could then do
INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name
Và tôi sẽ sẵn sàng. Siêu dễ dàng, phải không? Khá rõ ràng? Điều này chắc đã được thực hiện hàng trăm lần rồi. Chà, không!
Có một tiện ích được gọi là db_link
trong Postgres 9.1+, nhưng nó khá hạn chế vì áp dụng cú pháp sau:
SELECT fname, lname FROM db_link('host=localhost dbname=backup-28-08', 'SELECT fname, lname FROM users') AS remote (varchar255 fname varchar255 lname)
Mỗi tên cột cần được lặp lại hai lần bao gồm cả loại của nó. Khá nặng, chúng ta còn xa SELECT * FROM backup_db.table_name
đơn giản
Vì vậy, ý tưởng ở đây là sử dụng information_schema
nội dung bảng, mô tả từng bảng với tên cột, loại của nó, v.v. Tôi tìm thấy câu hỏi này trên SO: Chỉ định danh sách định nghĩa cột dblink từ một loại hiện có cục bộ
điều này đã giúp tôi rất nhiều (Cảm ơn bentrm
).
Nhưng giải pháp của nó là một quy trình gồm hai bước, đầu tiên là tạo một hàm, sau đó truy vấn nó:
SELECT dblink_star_func('dbname=ben', 'public', 'test');
SELECT * FROM star_test() WHERE data = 'success';
Và tôi vẫn đang nhắm tới 1 lớp lót. Sau một chút khó khăn (không phải là SQL Guru), đây là Gist: https://gist.github. com / augnustin / d30973ea8b5bf0067841
Bây giờ tôi có thể làm:
SELECT * FROM remote_db(NULL::users) -- (Still not 100% about why I need the NULL::)
-- And also
INSERT INTO users
SELECT * FROM remote_db(NULL::users)
Tuyệt vời, phải không?
3. Truy cập máy chủ cục bộ từ xa
Nếu cơ sở dữ liệu từ xa của bạn đã có sẵn trên internet (=có địa chỉ IP, tên miền, ví dụ:cho Heroku, nó sẽ giống như sau:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p
) bạn có thể bỏ qua bước này . Nhưng nếu bạn sử dụng cơ sở dữ liệu cục bộ của mình, bạn cần cung cấp nó từ thế giới bên ngoài (để cơ sở dữ liệu Heroku có thể truy cập nó).
Đối với điều này, tôi sử dụng ngrok tuyệt vời .
Sau khi cài đặt, tôi chỉ cần nhập lệnh sau:
ngrok -proto=tcp 5432 #5432 being the default port for Postgresql. (Adapt if necessary)
Tunnel Status online
Version 1.7/1.6
Forwarding tcp://ngrok.com:51727 -> 127.0.0.1:5432
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms
Và bạn chỉ cần cắm db_link
(in the gist) tới host=ngrock.com port=51727
và bạn tốt để đi !
4. Tiến xa hơn
Có thể có nhiều cải tiến cho điều này. Đây là một số tôi đã thấy:
- Coi tập lệnh là tính năng mặc định của
db_link
chức năng - Khả năng chống lỗi cao hơn nếu cấu trúc cơ sở dữ liệu khác nhau trong quá trình sao lưu và sản xuất
- Tạo công cụ so sánh giữa kết quả cơ sở dữ liệu và kết quả sao lưu (để chỉ trả về các dòng khác nhau)
- Xử lý các phép nối đơn giản
- Và xa hơn nữa là sẽ có một bộ điều hợp cấp ứng dụng (Ví dụ:ActiveRecord trong Rails) có thể cho phép thao tác các đối tượng phụ trợ thay vì SQL thô như hiện tại
Hy vọng tôi đã rõ ràng! Nếu không, vui lòng hỏi thêm chi tiết