出乎意料的簡單,原本還以為很麻煩的:django revert last migration – Stack Overflow
先執行 ./manage.py showmigrations my_app 列出所有的 migrations
然後執行 ./manage.py migrate my_app <0010_previous_migration>
這樣就可以 Revert 了。
Just thinking more…
出乎意料的簡單,原本還以為很麻煩的:django revert last migration – Stack Overflow
先執行 ./manage.py showmigrations my_app 列出所有的 migrations
然後執行 ./manage.py migrate my_app <0010_previous_migration>
這樣就可以 Revert 了。
邊看這篇 Celery – Best Practices 邊做的簡單摘錄與筆記。
CELERY_QUEUES = (
Queue('default', Exchange('default'), routing_key='default'),
Queue('for_task_A', Exchange('for_task_A'), routing_key='for_task_A'),
Queue('for_task_B', Exchange('for_task_B'), routing_key='for_task_B'),
)
CELERY_ROUTES = {
'my_taskA': {'queue': 'for_task_A', 'routing_key': 'for_task_A'},
'my_taskB': {'queue': 'for_task_B', 'routing_key': 'for_task_B'},
}
celery worker -E -l INFO -n workerA -Q for_task_A
celery worker -E -l INFO -n workerB -Q for_task_B
@app.task(bind=True, default_retry_delay=300, max_retries=5)
def my_task_A():
try:
print("doing stuff here...")
except SomeNetworkException as e:
print("maybe do some clenup here....")
self.retry(e) # Retry!
跟 Django 的整合可以參考 First steps with Django
裏面會要求你在 django app 的目錄下新增一個 celery.py,這裡有一行 app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) ,這行就是找到所有 tasks 的關鍵。找不到 task 的話,執行 python manage.py celeryd 時,不會有錯誤訊息,只在程式要執行這些 task 時印出錯務訊息,說找不到。
原始碼是在 celery/app/base.py 裡,大致就是依照 INSTALLED_APPS 列出的 package 去找 tasks,有的話就 import 進來。如果你的 celery task 沒有列在 INSTALLED_APPS 裡,或是函式不在 tasks 裡的話,可以再多加 app.autodiscover_tasks,例如 app.autodiscover_tasks([‘your_module’], related_name=’my_tasks’) ,這樣就可以引入使用了。
試用 python keyring 這個模組的一些紀錄:
同事問,為什麼用 model 建立 instance 以後,呼叫 save 沒有觸發 validate?
上網找了一下,大致有兩種方法:
事情沒有這樣結束,因為很好奇 Django 的作法,就去追 Code。
如果是走 is_valid() :
至此,ModelForm 的路徑就確定了。
來看看第二個方法,他是要求 Model 類別除了繼承 Django Model 之外,再繼承 ValidateModelMixin 這個自訂類別以覆寫 save() ,看看裏面的 save(),就只是多呼叫了 full_clean() 來檢查,也就是走上述步驟 4 以後的路線。
Django 官方網站不建議直接去呼叫 full_clean() 這件事,不過找了一下,也沒找到什麼更好的解法~
P.S.
會去追 code 主要是試著解決 Linux 下的 pip 不能用 IronPython 的問題,後來是沒解,但這是在去年年底時看的,我不知道現在是不是已經解決了。
pyenv install -l 這指令,大致做下面幾件事情:
因為 IronPython 2.7.5 才支援 pip,想要用 IronPython 2.7.5 (或更新的版本) ,可以這麼做:複製 .pyenv/plugins/python-build/share/python-build/ironpython-2.7.4 為 ironpython-2.7.5,把裏面的下載位址改為 https://github.com/IronLanguages/main/releases/download/ipy-2.7.5/IronPython-2.7.5.zip
這樣子,pyenv install -l 就會列出 ironpython-2.7.5,而且也可以下載安裝。
安裝 2.7.5 以後,用 pyenv shell ironpython-2.7.5 切換為 IronPython 2.7.5。
依照 2.7.5 的 release note 裡去執行 python -X:Frames -m ensurepip 時,卻出現以下的錯誤:
OSError: IronPython.Runtime.Exceptions.OSException: cannot load library at IronPython.Modules.CTypes.LoadLibrary (System.String library, Int32 mode) [0x00000] in <filename unknown>:0 at IronPython.Modules.CTypes.dlopen (System.String library, Int32 mode) [0x00000] in <filename unknown>:0 at Microsoft.Scripting.Interpreter.FuncCallInstruction`3[System.String,System.Int32,System.Object].Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) [0x00000] in <filename unknown>:0 at Microsoft.Scripting.Interpreter.Interpreter.Run (Microsoft.Scripting.Interpreter.InterpretedFrame frame) [0x00000] in <filename unknown>:0
會有這樣的錯誤,最主要是因為 ironpython-2.7.5/bin/Lib/ctypes/init.py 裡的 436~441 行,這裡是這樣寫的:
[python]
if _os.name in (“nt”, “ce”):
pythonapi = PyDLL(“python dll”, None, _sys.dllhandle)
elif _sys.platform == “cygwin”:
pythonapi = PyDLL(“libpython%d.%d.dll” % _sys.version_info[:2])
else:
pythonapi = PyDLL(None)
[/python]
這邊傳了 None 到 PyDLL,而 PyDLL 裡 (就 353 行) 的 _dlopen() 無法開啟 None ,才丟出這個 exception,有試著加程式處理掉這個 exception,但是,後續會因為這行
memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) 而出現 SystemError: LocalAlloc 錯誤
結論,Linux 下,IronPython 還是沒辦法用 pip ,另外就是,我不知道現在修正了沒。
碰到這個歡樂的錯誤,其實已經碰過兩三次了,前面幾次都不了了之。
InsecurePlatformWarning: A true SSLContext object is not available.
這次是確實的找到方法可以不用改程式避掉的方法,方法很簡單,就是安裝 pyopenssl ndg-httpsclient pyasn1 這幾個模組,這幾個模組會自動將 SSL 相關的憑證注射到 urllib3 模組裡,下載時就不會有 InsecurePlatformWarning 的警告。
這方法是在 StackOverflow 的 python – InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately 看到解法的,感謝。
今天用 pyenv 安裝了 3.4.2,卻發現沒有 tkinter 模組,經過一番明查暗訪,終於知道原因。原因就是沒安裝 tk8.5-dev (我是用 12.04,14.04 要改為 tk8.6-dev),用 apt-get 裝上 tk8.5-dev,然後重新用 pyenv 安裝一次 3.4.2 就可以了:pyenv install 3.4.2 。
換言之,用 pyenv 安裝特定版本的 Python 時,會因為當前環境是否有安裝必要函式庫的 header 而影響能使用的模組,以後要特別注意。
我是在 OpenShift 上遇到的情況,用 python3 + flask 寫的 web app 沒辦法啟動,用 rhc tail 出現這樣的錯誤訊息:
‘module’ object has no attribute ‘__loader__’
用 Google 找,在 StackOverflow 上找到這篇 flask – cannot setup apache 2.2 with mod_wsgi and python 3.3? ,然後跟著提供的線索看到這篇:Problem debugging Flask under Python 3.3 ,謝謝 Eric 提供的 workaround 。
workaround 是這樣的,在初使化 Flask(name) 時,加上 instance_path 參數,所以我就改為 Flask(name, os.path.join(os.environ[‘OPENSHIFT_PYTHON_DIR’], ‘instance’)) ,就解決了。
問題是出在 flask.Flask 的初始函數裡,Flask.init 在 instance_path 參數為 None 時,會呼叫 auto_find_instance_path() 來取得 instance_path 的值,而 auto_find_instance_path() 又呼叫 flask.helpers 的 find_packages(),find_packages() 使用了 pkgutil.get_loader() 來尋找 module 而導致了錯誤發生。
我在想,或許添加適當的 init.py 也可以解決,但就懶得做實驗了,先這樣。
剛好要整理照片,又懶得手動整理,就寫了 script 來處理。照片裡的資訊是放在圖片裡,也就是 EXIF,網路上已經有好心人寫好 exifread 模組,所以只要用 pip 裝上使用即可。想說只是簡單的程式,就沒使用 argparse 來解析參數了,第一個參數帶 *.jpg 或 *.png,第二個參數帶要複製過去的資料夾,例如 python photo_classifier.py *.jpg d:\tmp 即可。