![](/img/trans.png)
[英]Value too long for type character varying(255) SQLite3 to Postgres Django
[英]SQLite3 not catching username that's too long
最近,我修改了Django項目的設置,使其在運行測試而不是PostgreSQL時使用SQLite3,以便測試運行速度更快。 但是,一旦這樣做,我的一個否定單元測試就會檢查一次,以驗證如果我嘗試創建用戶名超過30個字符的用戶,Django將拋出錯誤,則該測試將失敗。 直到此時,測試始終通過。
如果我使用PostgreSQL運行以下測試,則會引發異常(特別是DatabaseError)並通過測試。 但是,如果我改用SQLite3,則不會引發異常並且測試失敗。 我仔細檢查了SQLite3 auth_user模式,並確認用戶名是varchar(30)字段。 其他人有沒有經歷過? 謝謝。
from django.test import TestCase
from django.contrib.auth.models import User
class SimpleTest(TestCase):
def test_simple(self):
exception_raised = True # Exception should be raised since username > 30 chars
try:
user = User.objects.create_user(username='testusertestusertestusertestuser')
except Exception as e:
exception_raised = False
assert not exception_raised, "Exception wasn't raised"
除了Zuko的答案外,我還會質疑您的單元測試可能做的不正確。
常見的誤解是,模型驗證是在保存之前進行的。 請參閱文檔以進行模型驗證 。
您正在執行的操作是希望在不通過驗證功能的情況下兌現模型字段的max_length
參數。 當您使用ModelForms
,表單將確保調用模型驗證,並且您將收到ValidationError
。
這同樣適用於其他約束,例如CharField
類型的is_blank
選項。 據我所知,這種驗證只能在Python領域進行,因為沒有可用的約束,您可以在數據庫級別應用此約束來檢查字段是否為空。
關於此問題,StackOverflow上還有許多其他問題,這些問題將解釋您如何在所有情況下都可以強制進行驗證,例如, 此答案
或者,讓您的單元測試調用full_clean()
實例方法來檢查是否滿足所有驗證約束。
我相信這是因為sqlite3在后台將所有varchar數據類型轉換為text數據類型。 這就是為什么DBMS不會捕獲任何超出您的限制的值的原因。 在這方面文檔尚不清楚,但是在文檔前后我都遇到了這個問題,這是我能想到的最佳答案。 所以基本上
CREATE TABLE A(name varchar(30))
最終將等同於:
CREATE TABLE A(name text)
在此處(第2.2節)中查看文檔: http : //www.sqlite.org/datatype3.html
您可以進行測試以查看這僅僅是DBMS的功能:
sqlite> create table A(name varchar(2));
sqlite> insert into A values("hello world");
sqlite> select * from A;
hello world
如您所見,沒有錯誤,也沒有截斷。
希望能有所幫助,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.