2010-08-13 36 views
13

Tôi cần di chuyển một dự án phức tạp từ sqlite sang PostgreSQL là gì. Rất nhiều người dường như gặp sự cố với khóa ngoại vi, cắt dữ liệu và v.v ...Django: Các phương pháp hay nhất để di chuyển dự án từ sqlite sang PosgreSQL

  • Có tiện ích tự động hoàn toàn không?
  • Tôi có cần kiểm tra một số dữ liệu hoặc lược đồ trước khi di chuyển không?

Sửa: Tôi cố gắng django-command-extensionsDumpScript nhưng nó không chạy trên 2GB RAM máy tính của tôi với DataSet hiện tại của tôi.

Trả lời

9

Tôi chưa bao giờ phải làm điều đó nhưng những gì tôi sẽ thử là.

  1. Ngừng chạy máy chủ
  2. python manage.py dumpdata
  3. Alter settings.py để trỏ đến cơ sở dữ liệu Postgres mới được tạo ra
  4. python manage.py LoadData
+1

python manage.py dumpdata -> ra khỏi bộ nhớ trên máy tính của tôi ... Nếu tôi cố gắng ứng dụng bằng cách ứng dụng, nó tốt hơn nhưng việc nhập khẩu không hoạt động . –

3

Trước tiên tôi 'd chỉ cần thử một cách đơn giản:

sqlite3 sqllitedb .dump | psql postgresdb 

Tại điểm đó, chỉ cần kiểm tra nó ra. Viết một số kịch bản thử nghiệm trong Django để xuất ra một tập hợp các bản ghi mẫu cho mỗi ứng dụng, và sau đó thực hiện một khác biệt để đảm bảo chúng giống hệt nhau. Nếu có, thì chuyển đổi của bạn có thể là tốt.

Nếu điều đó không làm việc ...

tôi khuyên bạn nên chống lại sử dụng Django để đổ và tải các dữ liệu, vì tôi đoán nó không được tối ưu hóa để làm như vậy. Thay vào đó, tôi sẽ tạo một phiên bản thứ hai của ứng dụng của bạn với các cài đặt cơ sở dữ liệu PostgreSQL chính xác, chạy syncdb để tạo tất cả các bảng, sau đó sao chép dữ liệu từ mysqllite sang PostgreSQL bằng một số công cụ khác.

Vấn đề là, hầu hết các vấn đề khi chuyển đổi qua dữ liệu nằm trong các định nghĩa bảng, v.v ... Có vẻ như đó là định dạng riêng nhất. Nếu bạn có thể tạo ra một kịch bản lệnh SQL là một kết xuất của các nội dung bảng, đó là các lệnh SQL INSERT INTO khá chuẩn.

Thành thật mà nói, tôi không thể thấy lý do tại sao có vấn đề chính ở nước ngoài. Giả sử rằng sqlite đang tạo ra các khóa ngoài chính xác (và tại sao nó không?) Thì không có cách nào không sao chép chính xác. Thực sự, các khóa ngoại không phải là các dạng dữ liệu đặc biệt. Không có khả năng trường UserProfile.user_id sẽ chứa giá trị không chính xác hơn trường UserProfile.photo. Nếu mối quan tâm chính của nước ngoài là các trường không được xác định chính xác là các trường khóa ngoài (nghĩa là không có ràng buộc), thì tùy chọn tạo cơ sở dữ liệu đầu tiên bằng cách sử dụng syncdb sẽ giải quyết vấn đề đó.

Theo cắt bớt: như tôi đã hiểu, PostgreSQL sẽ phát ra lỗi nghiêm trọng nếu dữ liệu sắp bị cắt bớt. Tôi không biết nếu đó là trường hợp với sqlite hoặc nếu nó chỉ truncates âm thầm. Dù bằng cách nào, một lần nữa giả sử sqlite không phải là bằng cách nào đó trộn dữ liệu khi xuất, các trường phải chứa dữ liệu có độ dài thích hợp cho trường mà nó đang đi vào.Điều duy nhất tôi có thể nghĩ về điều đó có thể ảnh hưởng đến điều này là mã hóa ký tự, vì vậy hãy chắc chắn rằng các trường PostgreSQL có cùng mã hóa như các bảng sqlite làm, ít nhất là trong quá trình nhập.

3

Một cách khác để thực hiện việc này có thể là sử dụng nhiều cơ sở dữ liệu.

http://docs.djangoproject.com/en/dev/topics/db/multi-db/

Điều quan trọng là bạn đọc phần này.

http://docs.djangoproject.com/en/dev/topics/db/multi-db/#moving-an-object-from-one-database-to-another

Từ những gì tôi hiểu rằng phương tiện đó được cung cấp không có dữ liệu trong DB mới của bạn, từ đồ đạc ví dụ bạn có thể làm

queryset = MyModel.objects.using("old-db").all() 
for obj in queryset: 
    obj.save(using="new-db") 

Vì rằng nên giữ gìn khóa chính I don' t nghĩ rằng có bất kỳ vấn đề chính nước ngoài.

23

Theo kinh nghiệm của tôi, việc bán & khôi phục từ SQL không hoạt động đúng cách.

Bạn nên làm theo trình tự này thay vì:

1. Nội dung Dump db để JSON

$ ./manage.py dumpdata > dump.json 

2. Chuyển các backend trong settings.py

DATABASES = { 
    # COMMENT OUT: 
    # 'default': dj_database_url.config(default='sqlite:////full/path/to/your/database/file.sqlite'), 
    # ADD THIS INSTEAD: 
    'default': dj_database_url.config(default='postgres://localhost:5432/postgres_db_name'), 
} 

3. Syncdb và di chuyển DB mới sang cùng cấu trúc bảng

$ ./manage.py syncdb 
$ ./manage.py migrate 

4. Nạp json vào db mới.

$ ./manage.py loaddata dump.json 

5. Chúc mừng! Bây giờ dữ liệu mới nằm trong db postgres của bạn.

+1

Cẩn thận, điều này chỉ dành cho các kích thước cơ sở dữ liệu nhỏ hơn http://stackoverflow.com/questions/23047766. loaddata tải toàn bộ json vào RAM có vẻ như – pufferfish

+7

Điều này gây ra lỗi: django.db.utils.IntegrityError: Vấn đề cài đặt fixture 'dump.json': Không thể tải contenttypes.ContentType (pk = 3): giá trị khóa trùng lặp vi phạm ràng buộc duy nhất "django_content_type_app_label_76bd3d3b_uniq" CHI TIẾT: Key (app_label, model) = (auth, group) đã tồn tại. – matandked

+2

Về lỗi của tôi trong bình luận cuối cùng có vẻ như bạn * cần * để áp dụng 'TRUNCATE django_content_type CASCADE;' * trước * bằng cách sử dụng loaddata. @Nimo bạn có thể cập nhật câu trả lời của mình không? – matandked

6

Sau đây là một sự tinh tế của Nimo's answerStephen's answer cho Django 1.7+:

  1. ./manage.py dumpdata --natural-primary --natural-foreign > dump.json
  2. Thay đổi DATABASES trong settings.py để trỏ đến mới (PostgreSQL) db.
  3. ./manage.py migrate
  4. ./manage.py loaddata dump.json

Một vấn đề tôi gặp phải là SQLite dường như không thực sự thực thi độ dài tối đa cho CharField s. Trong trường hợp của tôi, điều này làm cho bước loaddata không thành công. Tôi đã có thể tìm thấy (và xóa) trường hợp mô hình với CharField giá trị quá lâu qua:

MyModel.objects.extra(where=["LENGTH(text) > 20"]).delete() 

Một khi tôi đã làm điều này trước khi bước 1 ở trên, tất cả mọi thứ làm việc.

+0

Một vấn đề ở đây là di chuyển ghi dữ liệu (ví dụ: loại nội dung mặc định). Tôi di chuyển, sau đó tuôn ra, sau đó cắt bớt các chỉ mục về 0, * sau đó * loaddata. Đó là rất nhiều điều cần nhớ - và tôi luôn quên điều gì đó - nhưng hoạt động tốt. – Oli

1

Trong câu trả lời @Nimo, sử dụng từ "syncdb",
"syncdb" không làm việc trong django 1,9 (hoạt động trên django 1,7), thay vì đó, sử dụng như sau:

python manage.py migrate.

Và postgres thiết lập cấu hình là ở đây:

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.postgresql_psycopg2', 
     'NAME': 'myproject', 
     'USER': 'myprojectuser', 
     'PASSWORD': 'password', 
     'HOST': 'localhost', 
     'PORT': '', 
    } 
} 
Các vấn đề liên quan