Để chuyển đổi mã Python2 sang Python3, phiên bản nào của Python & Django phù hợp nhất?


11

Hiện tại tôi đang làm việc trong một công ty lớn, nơi chúng tôi cần chuyển đổi dự án Django cũ của python2 thành phiên bản python3 vì vậy tôi đã thực hiện nhiều nghiên cứu liên quan nhưng vẫn không thể tìm thấy câu trả lời hoàn hảo nào liên quan đến phiên bản Python và Django phù hợp nhất để chuyển đổi.

Hiện tại tôi đang sử dụng Python: 2.7.16 & Django: 1.9.13 trong phiên bản cũ của tôi.

Bất cứ ai cũng có thể gợi ý cho tôi phiên bản phù hợp nhất của Python & Django cho phiên bản cũ hơn để chuyển đổi python2 sang python3.


Phiên bản hiện tại của python3 là Python 3.8 và phiên bản mới nhất của Django là Django 3.0. Trang web của Django đề xuất phiên bản mới nhất của python 3 , là 3,8. Có một lý do cụ thể nào khiến bạn không muốn tăng tốc cả python và django lên các phiên bản gần đây nhất của chúng không?
Áo choàng xanh Guy

2
Thông thường, tôi chỉ nhận ra một vài ngày trước rằng trang web dựa trên Django mà tôi đã duy trì trong một vài năm nay thực sự chạy trên máy chủ được lưu trữ bằng python2.7, trong khi tôi đã chạy nó bằng python3. 7. Sự khác biệt duy nhất tôi tìm thấy là khi tôi cố gắng sử dụng chuỗi f ở đâu đó lần đầu tiên và phiên bản của máy chủ web bị lỗi; mặt khác, nó đã chạy chính xác như mong đợi (chính xác như nhau) cục bộ và từ xa, cho mục đích thử nghiệm và bổ sung tính năng. Kết luận hoàn toàn giai thoại của tôi là Django thường tương thích với hầu hết mọi thứ.
Áo choàng xanh Guy

1
đối với phiên bản mới nhất, tôi thấy rằng một số người không khuyến nghị vì trong phiên bản mới nhất nếu có bất kỳ vấn đề nào liên quan đến cập nhật mới thì đôi khi sẽ khó tìm giải pháp nên trong dự án hiện tại tôi không muốn tạo ra rủi ro như vậy & cũng cho Thử nghiệm purspose, tôi đã bắt đầu chuyển đổi dự án của mình sang phiên bản mới nhất python 3.7.3 với django mới nhất và đã tìm thấy 30 loại vấn đề.
Mặt trăng

Cần lưu ý - câu hỏi này đã đưa ra trong một cuộc đánh giá đánh giá cho tôi. "Có tài liệu hay tài liệu tham khảo nào không rõ ràng ngoài chủ đề (yêu cầu tài nguyên ngoài trang web). Tuy nhiên, tôi tin rằng câu hỏi có thể được chỉnh sửa sao cho tốt hơn có thể dẫn đến câu trả lời được chấp nhận dưới đây.
theMayer

Câu trả lời:


3

Tôi nghĩ rằng tôi sẽ thêm một chút vào chiến lược được ủng hộ bởi câu trả lời của Wim - hãy lấy phiên bản Django phù hợp hoạt động trên cả 2.7 và 3.x trước - và phác thảo một số chiến thuật phù hợp với tôi.

Python 2.7 là nhóm thoát của bạn, cho đến khi bạn bóp cò trên 3.x

  • bài kiểm tra của bạn nên chạy trên cả hai
  • không sử dụng bất kỳ tính năng cụ thể 3.x nào, như chuỗi f
  • đầu tiên là Python 3.x, sau đó chỉ sau Django 2.x không chạy trên 2.7
  • bắt đầu sớm, đừng phân tích quá mức, nhưng tránh cách tiếp cận vụ nổ lớn
    • tập tin theo tập tin lúc đầu
    • bắt đầu với mã cấp thấp nhất, như thư viện tiện ích, mà bạn có bộ kiểm tra.
    • nếu có thể, hãy cố gắng hợp nhất dần các thay đổi của bạn với các nhánh sản xuất 2.7 và giữ cho mã cổng 3.x của bạn được cập nhật với các thay đổi prod.

Phiên bản nhỏ nào của Django để bắt đầu?

Tiêu chí của tôi ở đây là việc di chuyển Django có thể tham gia khá nhiều (và thực sự đòi hỏi nhiều suy nghĩ hơn 2 => 3 công việc). Vì vậy, tôi sẽ chuyển sang bản 1.11 mới nhất và lớn nhất theo cách mà bạn đã cung cấp một số giá trị cho 2.7 người dùng của bạn. Có lẽ có một số lượng tốt khả năng tương thích trước 2.x trên 1.11 bạn sẽ nhận được cảnh báo khấu hao 2.x của nó.

Phiên bản nhỏ nào của Python 3.x để bắt đầu?

Tốt nhất để xem xét tất cả các góc độ, chẳng hạn như tính khả dụng của libs bên thứ 3 của bạn, hỗ trợ từ bộ CI / devops và tính khả dụng trên hình ảnh hệ điều hành máy chủ đã chọn của bạn. Ví dụ, bạn luôn có thể cài đặt 3,8 và thử cài đặt pip của tệp.txt.txt của mình.

Tận dụng git (hoặc bất cứ thứ gì bạn sử dụng scm) và virtualenv .

  • tách rời requirement.txtcác tệp , nhưng ...
  • nếu bạn có một repo dựa trên tệp, bạn có thể trỏ từng venv tại cùng một dòng mã với a pip install -e <your directory>. điều đó có nghĩa là, trong 2 thiết bị đầu cuối khác nhau, bạn có thể chạy 2,7 ​​và 3.x so với cùng một (các) đơn vị khác nhau.
  • bạn thậm chí có thể chạy các máy chủ Django 2.7 và 3.x cạnh nhau trên các cổng khác nhau và nói rằng Firefox và Chrome ở đó.
  • cam kết thường xuyên (ít nhất là trên nhánh porting) và tìm hiểu về git bisect .

tận dụng 2to3

Có, nó sẽ phá vỡ mã 2.7 và Django nếu bạn để nó. Vì thế...

  • chạy nó trong chế độ xem trước hoặc đối với một tập tin duy nhất. xem những gì nó phá vỡ nhưng cũng thấy những gì nó đã làm đúng.

  • điều chỉnh nó để chỉ một số chuyển đổi nhất định không phá vỡ 2.7 hoặc Django. print x=> print (x)except(Exception) as elà 2 người không có trí tuệ.

Đây là những gì lệnh điều chỉnh của tôi trông giống như:

2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
  • chạy nó từng tập tin cho đến khi bạn thực sự tự tin.

sử dụng sed hoặc awk thay vì trình chỉnh sửa của bạn để chuyển đổi hàng loạt.

Ưu điểm là, khi bạn nhận thức rõ hơn về mối quan tâm cụ thể của ứng dụng của mình, bạn có thể xây dựng một bộ thay đổi có thể chạy trên 1 tệp hoặc nhiều tệp và thực hiện hầu hết công việc mà không phá vỡ 2.7 hoặc Django. Áp dụng điều này sau khi vượt qua 2to3 phù hợp của bạn . Điều đó khiến bạn phải dọn dẹp dư thừa trong trình chỉnh sửa của mình và vượt qua các bài kiểm tra.

(tùy chọn) bắt đầu chạy màu đen trên mã 2.7.

màu đen là một trình định dạng mã, sử dụng Python 3 AST để chạy phân tích của nó. Nó không cố chạy mã, nhưng nó sẽ đánh dấu các lỗi cú pháp ngăn nó đến giai đoạn AST. Bạn sẽ phải làm việc một số pip cài đặt ma thuật toàn cầu để đến đó và bạn phải mua tính hữu dụng của màu đen.

Những người khác đã làm điều đó - học hỏi từ họ.

Nghe # 155 Các bước thực tế để chuyển sang Python 3 sẽ cung cấp cho bạn một số ý tưởng về công việc. Nhìn vào các liên kết hiển thị cho nó. Họ thích nói về động thái trên Instagram (?) Liên quan đến việc điều chỉnh dần dần việc chạy mã 2.7 thành cú pháp 3.x trên một cơ sở mã thông thường và trên cùng một nhánh git, cho đến ngày kéo.

Xem thêm Hướng dẫn chuyển đổi Python 3 bảo thủ

Instagram giúp di chuyển mượt mà lên Python 3 - Ngăn xếp mới

Phần kết luận

Thời gian của bạn để Django 1.11 EOL (tháng 4 năm 2020) khá ngắn, vì vậy nếu bạn có hơn 2 tài nguyên dev để sử dụng, tôi sẽ xem xét thực hiện song song các bước sau:

  • DEV # 1: bắt đầu với một cú va chạm Django 1.11 (lý thuyết cho rằng Django 1.11 có thể được định vị tốt nhất như một điểm nhảy ra Django 2.x), sử dụng 2.7.

  • DEV # 2: bắt đầu với Python 3.6 / 3.7 của mã tiện ích không phải Django của bạn. Vì mã này tương thích 2.7 tại thời điểm này, hãy hợp nhất nó thành # 1 khi bạn đi.

Xem cách cả hai nhiệm vụ tiến hành, đánh giá rủi ro dự án liên quan đến Django là gì và nỗi đau của Python 3 trông như thế nào. Bạn đã thiếu Python 2.7 EOL, nhưng một khung web lỗi thời có lẽ nguy hiểm hơn so với Python 2.7 cũ, ít nhất là trong vài tháng. Vì vậy, tôi sẽ không chờ đợi quá lâu để bắt đầu di chuyển khỏi Django 1.9 và công việc của bạn sẽ không bị lãng phí. Khi bạn thấy tiến độ, bạn sẽ bắt đầu thấy rủi ro dự án tốt hơn.

Tiến trình 2to3 ban đầu của bạn sẽ chậm, nhưng công cụ và hướng dẫn đủ tốt để bạn nhanh chóng tăng tốc, vì vậy đừng lật đổ nó trước khi bắt đầu thu thập kinh nghiệm. Phía Django phụ thuộc vào mức độ tiếp xúc của bạn đối với các thay đổi trong khung, đó là lý do tại sao tôi nghĩ tốt nhất nên bắt đầu sớm.

PS (tranh cãi / ý kiến ​​cá nhân) Tôi đã không sử dụng sáu hoặc nhiều thư viện cầu 2 đến 3 đóng hộp khác.

Không phải vì tôi không tin tưởng nó - thật tuyệt vời cho các lib của bên thứ 3 - mà là tôi không muốn thêm một phụ thuộc vĩnh viễn phức tạp (và tôi quá lười để đọc tài liệu của nó). Tôi đã viết 2.7 mã theo cú pháp tương thích 3.x trong một thời gian dài vì vậy tôi không thực sự cảm thấy cần phải sử dụng chúng. Số dặm của bạn có thể thay đổi và không được đặt ra trên con đường này nếu nó có vẻ như rất nhiều công việc .

Thay vào đó, tôi đã tạo một py223.py (57 LỘC bao gồm các bình luận) với loại nội dung này, hầu hết đều liên quan đến cách giải quyết cho sự phản đối và thay đổi tên trong thư viện chuẩn.

try:
    basestring_ = basestring
except (NameError,) as e:
    basestring_ = str

try:
    cmp_ = cmp
except (NameError,) as e:
    # from http://portingguide.readthedocs.io/en/latest/comparisons.html
    def cmp_(x, y):
        """
        Replacement for built-in function cmp that was removed in Python 3
        """
        return (x > y) - (x < y)

Sau đó nhập từ py223 đó để giải quyết những mối quan tâm cụ thể đó. Sau này tôi sẽ bỏ việc nhập khẩu và chuyển những thứ kỳ lạ đó isinstance(x, basestr_)sang isinstance(x, str)nhưng tôi biết trước có chút lo lắng.


Lời khuyên tốt. Chỉ cần một lưu ý, bản thân Django đã sử dụng sixcho lớp tương thích, vì vậy nếu bạn muốn sử dụng nó trong dự án Django trong quá trình chuyển đổi, thì đây không phải là "thêm một phụ thuộc vĩnh viễn phức tạp".
wim

@wim. Tôi đồng ý với bạn. sáu, nhưng nó phụ thuộc vào quan điểm. Tôi đã lưu ý rằng nó đi kèm với libs của bên thứ 3, vì vậy nó không "tốn kém" về các yêu cầu và phụ thuộc tổng thể. tuy nhiên tôi - có thể sai - coi đó là một hộp đen lớn / mụn cóc ở giữa mã của tôi . nếu tất cả những gì bạn đang làm là những thứ như kiểm tra chuỗi / unicode / basestring và nếu bạn biết cách tự làm điều đó, thì bạn biết chính xác làm thế nào để loại bỏ các shims của mình khi không cần thiết nữa. Tôi sẽ di chuyển đến cuối cùng, mặc dù.
JL Peyret

Đó là pip install -e ...(với một chữ thường -e), phải không?
thebjorn

nó có thể là sẽ sửa
JL Peyret

3

Đề nghị của tôi là đầu tiên nâng cấp lên Django==1.11.26 , đây là phiên bản mới nhất của Django đang hỗ trợ cả Python 2 và Python 3. Hiện tại vẫn là phiên bản Python 2.7 hiện tại của bạn.

Đọc kỹ các ghi chú phát hành cho 1.10.x và 1.11.x, kiểm tra khấu hao và sửa bất cứ thứ gì ngừng hoạt động từ mã 1.9.x của bạn. Mọi thứ S break bị phá vỡ. Django di chuyển nhanh. Đối với một dự án Django lớn, có thể cần nhiều thay đổi mã và nếu bạn đang sử dụng nhiều plugin hoặc thư viện của bên thứ 3, bạn có thể phải xử lý các phiên bản của chúng xung quanh. Một số phụ thuộc bên thứ 3 của bạn có thể đã bị bỏ hoàn toàn, vì vậy bạn phải tìm thay thế hoặc xóa các tính năng.

Để tìm ghi chú phát hành cho mỗi phiên bản nâng cấp, chỉ cần google "Có gì mới trong Django". Các lượt truy cập sẽ ghi lại một cách tỉ mỉ tất cả các khấu hao và thay đổi:

Khi ứng dụng web có vẻ hoạt động tốt trên Django 1.11, với tất cả các thử nghiệm đã qua (bạn làm có một bộ kiểm tra, phải không?) Sau đó bạn có thể làm việc chuyển đổi Python 3, trong khi vẫn giữ các phiên bản Django giống nhau. Django 1.11 hỗ trợ lên tới Python 3.7, vì vậy đó sẽ là một phiên bản tốt để nhắm mục tiêu. Mong đợi unicode ở khắp mọi nơi, vì các chuyển đổi ngầm định giữa byte và văn bản đã biến mất và nhiều ứng dụng web Python 2 đã dựa vào đó.

Khi dự án có vẻ hoạt động tốt trên Django 1.11 và Python 3.7, bạn có thể nghĩ đến việc nâng cấp lên Django 3.0, theo quy trình tương tự như trước - đọc ghi chú phát hành, thực hiện các thay đổi cần thiết, chạy bộ kiểm tra và kiểm tra webapp trong một máy chủ dev bằng tay.


1
Chắc chắn là con đường để đi. Nhận mã kiểm tra của bạn để chạy trên cả 2.7 và 3.x. Bạn có thể có 2 virtualenv khác nhau trỏ vào cùng một repo git với pip install -E. Khi các bài kiểm tra đơn vị đang chạy, hãy bắt đầu sử dụng thử nghiệm Django-on-3x và một lần nữa giữ mã hoạt động trong 2 và 3. Với một số mã hóa cẩn thận và cẩn thận không đốt cầu 2.7 của bạn - ví dụ như không có chuỗi f - việc chuyển đổi sẽ là rất phản trắc. Khi 3.x hoàn toàn ổn định, hãy bắt đầu sử dụng mã 3.x. Ưu điểm là sản xuất 2.7 luôn được thực hiện cho đến khi chuyển đổi.
JL Peyret

2

Tôi sẽ nâng cấp lên py3 trước. Bạn sẽ cần xem setup.pytrong repo Django trên nhánh ổn định / 1.9.x ( https://github.com/django/django/blob/ sóng / 9.9.x / setup.py ) để tìm ra py3 các phiên bản được hỗ trợ là 3,4 (chết) và 3,5.

Khi bạn đang sử dụng py3.5 và Django 1.9, bạn có thể nâng cấp từng cái một cho đến khi bạn đến phiên bản bạn muốn kết thúc. Ví dụ: Django 1.11 hỗ trợ py3.5 và py3.7, vì vậy

py27/dj19 -> py35/dj19 -> py35/dj1.11 -> py37/dj1.11 ... -> py37/dj2.2

dj2.2 là phiên bản đầu tiên hỗ trợ py3.8, nhưng tôi có lẽ sẽ dừng lại ở py37 / dj2.2 nếu bạn làm việc trong một môi trường bình thường bảo thủ.

Nếu bạn có các gói khác, bạn sẽ cần tìm các kết hợp phiên bản sẽ hoạt động cùng nhau trên mỗi bước. Có một kế hoạch là chìa khóa và chỉ nâng cấp một thành phần tại một thời điểm thường sẽ giúp bạn tiết kiệm thời gian.

Thư viện trong tương lai ( https://python-future.org/ ) sẽ giúp bạn với nhiều tình huống khó khăn trong khi bạn cần mã để chạy trên cả py27 và 3.x. sáu là tuyệt vời quá. Tôi sẽ tránh lăn lớp tương thích của riêng bạn (tại sao lại phát minh lại bánh xe?)

Nếu có thể, hãy thử bảo hiểm thử nghiệm đơn vị của bạn lên đến 75-85% trước khi bắt đầu và chắc chắn thiết lập thử nghiệm tự động trên cả hai phiên bản "từ" và "đến" cho mỗi bước nâng cấp. Hãy chắc chắn rằng bạn đã đọc và sửa tất cả các cảnh báo từ Django trước khi nâng cấp lên phiên bản tiếp theo - Django quan tâm rất ít đến khả năng tương thích ngược, vì vậy tôi thường khuyên bạn nên nhấn mọi phiên bản nhỏ trên đường nâng cấp (hoặc ít nhất là đảm bảo bạn đọc "ngược" không tương thích "và danh sách khấu hao cho từng phiên bản nhỏ).

Chúc may mắn (chúng tôi đang nâng cấp cơ sở mã 300 + Kloc từ py27 / dj1.7 ngay bây giờ, vì vậy tôi cảm thấy nỗi đau của bạn ;-)


1
+1 về phạm vi kiểm tra. Đó là một số liệu quan trọng ở đây, bất cứ cách tiếp cận nào người ta kết thúc. Nó thực sự hữu ích khi thử nghiệm các thay đổi mã phổ biến và tôi đang nói điều này với tư cách là một người hoàn toàn không phải là người hâm mộ thử nghiệm TDD Red / Green. Chỉ ra một cách để căn cứ vào kết quả 2.7 của bạn và việc nâng cấp trở nên dễ dàng hơn rất nhiều.
JL Peyret

2

Tôi có cùng loại vấn đề với dự án của mình và tôi đã thử dùng python 3.7.5 với phiên bản Django 2.2.7.

Bạn không nên dùng python phiên bản mới nhất 3.8 hoặc Django phiên bản 3.0 mới nhất vì bạn có thể có bất kỳ loại lỗi nào mà bạn không thể có được giải pháp thích hợp cho các phiên bản mới nhất.


Đây phải là một bình luận
Bruno

-2

Bạn nên cố gắng chụp cho các phiên bản hiện tại. Python 3.8 và Django 3.0. Thư viện Six sẽ giúp thay đổi quy ước. Dù bằng cách nào bạn sẽ phải thực hiện một số tái cấu trúc để bạn cũng có thể làm cho nó hiện tại.


3
Bạn đã bao giờ thực hiện nâng cấp Django chưa? Đây chỉ là mơ tưởng. Truy cập trực tiếp vào Python 3.8 và Django 3.0 từ 2.7 / 1.9 sẽ gần như không thể. Ngay cả việc nâng cấp các phiên bản nhỏ như Django 1.9 lên 1.10 có thể là một quá trình khó khăn, với nhiều thay đổi mã cần thiết.
wim

Có, tôi đã có, tôi đã có sự chấp thuận sang trọng và thời gian để thực hiện một bộ tái cấu trúc hoàn chỉnh và đưa ứng dụng hiện tại. Một lần nữa kích thước ứng dụng, logic và hạn chế thời gian là một vấn đề lớn đối với hầu hết mọi người nhưng họ không bao giờ đề cập đến kích thước ứng dụng hoặc hạn chế thời gian, vì vậy tôi đã đề xuất ý kiến ​​của tôi về "giải pháp tốt nhất" hoặc "suy nghĩ mơ ước";)
Dave

ngoài ra, nếu bạn phải lo lắng về những thứ Ansible và chạy trên LTS Ubuntu, bạn sẽ thấy ngay cả hỗ trợ 3.7 cũng thiếu trên Ubuntu 18.04. Các podcast bảo mật tôi lắng nghe khuyên 3,8 nên giải quyết một chút cho đến khi phát hành điểm hoặc 2. -1 cho rủi ro không cần thiết.
JL Peyret

Bất kỳ khuyến nghị podcast bảo mật tốt?
Dave

Đối với Python sec, listennotes.com/podcasts/talk-python-to-me/ , Nhưng tôi nghĩ rằng phần mềm của 3,8-for-a-while là một cái gần đây hơn. Risky Business là một podcast bảo mật tốt và thú vị, đặc biệt nếu bạn theo dõi các mối quan hệ quốc tế. Xin lỗi vì downvote, nhưng vâng, những gì hoạt động trong trường hợp của bạn có thể làm thất vọng người khác trong một bối cảnh khác. Để chuyển đổi từ 2 đến 3, hãy xem listennotes.com/podcasts/talk-python-to-me/iêu
JL Peyret
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.