Zmiana nazwy folderu virtualenv bez niszczenia go

162

Utworzyłem folder i zainicjowałem w nim instancję virtualenv.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Kiedy uruchamiam (env)$ pip freeze, pokazuje zainstalowane pakiety tak, jak powinno.

Teraz chcę zmienić nazwę myproject/na project/.

$ mv myproject/ project/

Jednak teraz, kiedy biegnę

$ . env/bin/activate
(env)$ pip freeze

mówi, że pip nie jest zainstalowany. Jak zmienić nazwę folderu projektu bez niszczenia środowiska?

Riley Watkins
źródło
1
To pytanie jest stare i ma już odpowiedź, ale muszę się zastanawiać, dlaczego OP nie mógł po prostu przenieść virtualenv z powrotem do miejsca, w którym był? Oczywiście nie rozwiązuje to chęci przeniesienia / zmiany nazwy, ale czy nie przywróci to działającego virtualenv, czy jest już beznadziejnie zepsuty?
Malik A. Rumi
2
Tak, masz rację, naprawiłoby to wirtualne środowisko, ale nie rozwiązałoby problemu.
Florian
Listopad 2019, Python3. Najlepsze dla mnie rozwiązanie jest opisane w aarongorka.com/blog/portable-virtualenv
Samir Sadek

Odpowiedzi:

148

Musisz dostosować swoją instalację, aby używała ścieżek względnych. virtualenvprzewiduje to za pomocą --relocatableopcji. Z dokumentów :

Zwykle środowiska są powiązane z określoną ścieżką. Oznacza to, że nie możesz przenieść środowiska dookoła ani skopiować go na inny komputer. Możesz naprawić środowisko, aby było przenoszone za pomocą polecenia:

$ virtualenv --relocatable ENV

UWAGA: ENV to nazwa środowiska wirtualnego, które należy uruchomić spoza katalogu ENV.

Spowoduje to, że niektóre pliki utworzone przez setuptools lub dystrybucję będą używać ścieżek względnych i zmieni wszystkie skrypty tak, aby korzystały z activ_this.py, zamiast używać lokalizacji interpretera Pythona do wybierania środowiska.

Uwaga: musisz to uruchomić po zainstalowaniu jakichkolwiek pakietów w środowisku. Jeśli zmienisz lokalizację środowiska, a następnie zainstalujesz nowy pakiet, musisz ponownie uruchomić virtualenv --relocatable.

ire_and_curses
źródło
2
caveat: Zmiana env na relocatable to coś więcej niż tylko przeniesienie folderu. (patrz uwaga: skopiowane z dokumentacji) ... może mieć skutki uboczne.
Ben Roberts,
7
Opcja --relocatable ma obecnie wiele problemów i nie gwarantuje działania w każdych okolicznościach. Jest możliwe, że opcja zostanie wycofana w przyszłej wersji virtualenv. Nie powoduje to również, że pakiety są wieloplatformowe. Możesz przenosić katalog, ale można go używać tylko na innych podobnych komputerach.
Demz
1
@TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venvpomoże znaleźć wszystkie shabangi, które używają starego venv, ale nie jest pełną weryfikacją przeniesionego venv.
płyty grzewcze
2
Będziesz także musiał edytować .projectplik virtualenvwrapper , który zawiera ścieżkę do kodu źródłowego zależnego od virtualenv, zakładając, że używasz virutalenvwrapper, a także zmieniłeś nazwę katalogu projektu, aby pasował do nowego virtualenv.
płyty grzewcze
Musiałem dezaktywować virtualenv przed uruchomieniem tego.
antonagestam
108

Uważam, że „wiedzieć dlaczego” jest ważniejsze niż „wiedzieć jak” . Oto inne podejście do rozwiązania tego problemu.

Po uruchomieniu . env/bin/activatefaktycznie wykonuje następujące polecenia ( /tmpna przykład używając ):

VIRTUAL_ENV="/tmp/myproject/env"
export VIRTUAL_ENV

Jednak właśnie zmieniłeś nazwę myprojectna project, więc to polecenie nie zostało wykonane. Dlatego mówi pip is not installed, ponieważ nie zainstalowałeś pipw globalnym środowisku systemu, a twój virtualenv pipnie jest prawidłowo pozyskiwany.

Jeśli chcesz to naprawić ręcznie, oto sposób:

  1. W swoim ulubionym edytorze, takim jak Vim, modyfikuj /tmp/project/env/bin/activatezwykle w linii 42:

    VIRTUAL_ENV='/tmp/myproject/env' => VIRTUAL_ENV='/tmp/project/env'

  2. Zmień /tmp/project/env/bin/pipw linii 1:

    #!/tmp/myproject/env/bin/python => #!/tmp/project/env/bin/python

Następnie envponownie aktywuj swoje wirtualne środowisko , a zobaczysz, że pipwróciłeś.

Holys
źródło
6
Jeśli wymagana jest ręczna zmiana ścieżek, należy zauważyć, że istnieje więcej niż dwa pliki zakodowane na stałe. Znajdź je wszystkie z czymś takim: grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. W rzeczywistości zauważyłem, że w jednej z moich instancji Django wiele pakietów zawierało „ścieżkę do Pythona sh-bang”.
Kevin
To mi bardzo pomogło. Zdecydowanie musiałem wiedzieć, dlaczego ... Dzięki!
Jarvis
W przeciwieństwie do powyższego komentarza Kevena, uważam, że edycja tych dwóch linii rozwiązuje wszystkie problemy związane z przenoszeniem virtualenv. Być może jest jakiś przypadek użycia, którego nie używam, więc nie napotykam problemu.
Deleet
Podrap to! Dzisiaj napotkałem problem: ipython nie działał w ramach virtualenv. Aby rozwiązać ten problem, wyedytowałem nagłówek bash (jak to się nazywa?) W ipythonpliku i wszystko działało dobrze.
Deleet
Hmm, to nie działa dla mnie i wygląda na to, że mój skrypt aktywacyjny nie ma linii 1, do której jest mowa w kroku 2. Czy coś się zmieniło?
Evan Zamir,
40

UWAGA: As @jb. zwraca uwagę, to rozwiązanie dotyczy tylko łatwych (ponownie) utworzonych virtualenvplików. Jeśli instalacja środowiska zajmuje kilka godzin, to rozwiązanie nie jest zalecane


Wirtualne maszyny są świetne, ponieważ są łatwe do wykonania i przełączania; zapobiegają zamknięciu się w jednej konfiguracji. Jeśli znasz wymagania projektu lub możesz je zdobyć, utwórz nowyvirtualenv :

  • Utwórz requirements.txtplik

    (env)$ pip freeze > requirements.txt

    • Jeśli nie możesz utworzyć requirements.txtpliku, sprawdź env/lib/pythonX.X/site-packagesprzed usunięciem oryginału env.
  • Usuń istniejące (env)

    deactivate && rm -rf env

  • Utwórz nowy virtualenv, aktywuj go i zainstaluj wymagania

    virtualenv env && . env/bin/activate && pip install -r requirements.txt


Alternatywnie, użyj virtualenvwrapper, aby trochę ułatwić, ponieważ wszystkie virtualenv są przechowywane w scentralizowanej lokalizacji

$(old-venv) pip freeze > temp-reqs.txt
$(old-venv) deactivate
$ mkvirtualenv new-venv
$(new-venv) pip install -r temp-reqs.txt
$(new-venv) rmvirtualenv old-venv
bnjmn
źródło
6
Cóż, dla niektórych osób pip install -r requirements.txtzajmuje to kilka godzin (kompilacja rozszerzeń C innych firm na raspberry pi).
jb.
4
Może to prawda, ale wydaje mi się to kwestią krytyczną. Nadal uważam, że może to być realne rozwiązanie w wielu przypadkach.
bnjmn
Tak, wiele projektów (na przykład witryna Django) zajmuje tylko 30 sekund, aby zainstalować wszystko, nawet jeśli mają kilkadziesiąt zależności (pod warunkiem, że najpierw pobierzesz wszystko i użyjesz '--no-index --find-links = downloadDir' )
Jonathan Hartley
1
@bnjmn one-liner virtualenv env && pip install -r requirements.txtNIE zainstaluje wymagań w nowym środowisku, ponieważ go nie aktywujesz
Yarin
1
@Yarin Dzięki za wskazanie tego. Całkowicie to przegapiłem, będąc virtualenv-wrapperużytkownikiem (który automatycznie aktywuje się podczas tworzenia). Zaktualizowałem swoją odpowiedź, aby zawierała aktywację virtualenvw nadziei uniknięcia nieporozumień.
bnjmn
28

Aby pomóc, zawsze instaluję virtualenvwrapper. Z wiersza polecenia powłoki:

pip install virtualenvwrapper

Jest sposób udokumentowany w dokumentach virtualenvwrapper - cpvirtualenv To właśnie robisz. Upewnij się, że jesteś poza środowiskiem i wróć do znaku zachęty powłoki. Wpisz to z wymaganymi nazwami:

cpvirtualenv oldenv newenv

A następnie, jeśli to konieczne:

rmvirtualenv oldenv

Aby przejść do swojego newenv:

workon newenv
Afrowave
źródło
1
Odpowiedź Afrowave naprawdę powinna być zaakceptowaną metodą.
Jaxian,
Działa to tylko wtedy, gdy używasz virtualenvwrapper, a nie tylko virtualenv. Ta odpowiedź od @ryankdwyer jest lepsza.
LS
Zredagowałem moją odpowiedź, aby odzwierciedlić, że należy zainstalować „virtualenvwrapper”. Zakładając, że zmiana nazw środowisk wirtualnych zdarza się dużo, poleciłbym ten sposób.
Afrowave
Mimo że opiera się na virtualenvwrapper, jest najprostszy. I działa dobrze.
blasrodri
17

Możesz rozwiązać problem, wykonując następujące czynności:

  1. zmień nazwę katalogu
  2. uruchom to ponownie: $ virtualenv ..\path\renamed_directory
  3. virtualenv poprawi powiązania katalogów, pozostawiając pakiety na miejscu
  4. $ scripts/activate
  5. $ pip freeze aby sprawdzić, czy paczki są na miejscu
  6. Ważne ostrzeżenie, jeśli masz jakiekolwiek zależności ścieżek statycznych w plikach skryptów w katalogu virtualenv, będziesz musiał je ręcznie zmienić.
ryankdwyer
źródło
1
To było dla mnie bardzo dobre rozwiązanie. Ponieważ to rozwiązanie może uniknąć niektórych problemów z nim związanych --relocatable, myślę, że to rozwiązanie jest lepsze niż zaakceptowana odpowiedź. Do tej pory zauważyłem, że wiele .pycplików _new_name_/lib/python2.7nadal odwołuje się do _old_name_. Jednak wydaje się, że nie ma to wpływu na działanie mojego środowiska. Być może jedynym lepszym rozwiązaniem jest użycie virtualenvwrapperlub niektórych innych narzędzi wymienionych w odpowiedziach tutaj. Przynajmniej to rozwiązanie nie wymaga instalowania dodatkowych programów.
LS
Działa jak marzenie!
AmirHossein
13

Innym sposobem na zrobienie tego, który działał u mnie wiele razy bez problemów, jest virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env
Antony Hatchkins
źródło
Należy to oznaczyć jako najlepszą odpowiedź. Ręce na dół! Sklonowanie zajęło trochę czasu, więc miej cierpliwość.
Amitrajit Bose
virtualenv-clone zaniedbuje aktualizację monitu. Musiałem to zrobić ręcznie. Poza tym jest świetny.
user3667349
5

(wewnątrz folderu projektu)

cd bin
sed -i 's/old_dir_name/new_dir_name/g' *

Nie zapomnij dezaktywować i aktywować

Ignacio
źródło
Działa dobrze; Lub dla ścieżki Linuksa:sed -i "s|$old_dir|$new_dir|g" bin/*
Destroyica
sed -i '.original' 's/old_dir_name/new_dir_name/g' *dla komputerów Mac
Alex
1

virtualenv --relocatable ENVnie jest pożądanym rozwiązaniem. Zakładam, że większość ludzi chce mieć możliwość zmiany nazwy virtualenv bez żadnych długoterminowych skutków ubocznych.

Stworzyłem więc proste narzędzie, które to robi. Strona projektu dla virtualenv-mv przedstawia go nieco bardziej szczegółowo, ale zasadniczo możesz używać virtualenv-mvtak, jakbyś używał prostej implementacji mv(bez żadnych opcji).

Na przykład:

virtualenv-mv myproject project

Pamiętaj jednak, że właśnie to zhakowałem. Może się zepsuć w nietypowych okolicznościach (np. Wirtualneenvs z dowiązaniem symbolicznym), więc bądź ostrożny (wykonaj kopię zapasową tego, czego nie możesz stracić) i daj mi znać, jeśli napotkasz jakiekolwiek problemy.

Sześć
źródło