将多个处理器与django nose一起使用会产生DatabaseError

将多个处理器与django nose一起使用会产生DatabaseError,django,postgresql,multiprocessing,factory-boy,django-nose,Django,Postgresql,Multiprocessing,Factory Boy,Django Nose,我正在尝试使用带有多个处理器的django nose运行我们的测试套件,以减少运行时间。所有测试都通过一个处理器,但使用多个处理器会产生一个数据库错误:服务器意外地关闭了连接 我发现两个测试在多个处理器上运行时,90%的时间失败。UserFactory正在处理accounts\u user和CustomerFactory正在处理accounts\u customer。注意在传递日志中,在交易结束之前,完成对客户的最终更新。在失败日志中,此更新至账户(客户从未发生,因为交易已关闭,导致数据库错误:

我正在尝试使用带有多个处理器的
django nose
运行我们的测试套件,以减少运行时间。所有测试都通过一个处理器,但使用多个处理器会产生一个
数据库错误:服务器意外地关闭了连接

我发现两个测试在多个处理器上运行时,90%的时间失败。
UserFactory
正在处理
accounts\u user
CustomerFactory
正在处理
accounts\u customer
。注意在传递日志中,在交易结束之前,完成对
客户
的最终
更新
。在失败日志中,此
更新
账户(客户
从未发生,因为交易已关闭,导致
数据库错误:服务器意外关闭连接

我正试图确定是什么导致了这个问题。我认为问题最有可能是django或postgres如何处理交易,但可能是以下任何一种

  • django 1.7
  • python 2.7
  • 博士后
通过postgres日志:

145 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: SELECT * FROM "accounts_customer" INNER JOIN "accounts_user" ON ( "accounts_customer"."user_ptr_id" = "accounts_user"."id" ) WHERE "accounts_user"."email" = 'testJkQS.userUksx@example.com' LIMIT 21
146 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  duration: 1.927 ms
147 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: SAVEPOINT "s140735112696576_x1"
148 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  duration: 0.041 ms
149 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: SELECT (1) AS "a" FROM "accounts_customer" WHERE "accounts_customer"."account_number" = '87611264' LIMIT 1
150 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  duration: 0.187 ms
151 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: INSERT INTO "accounts_user" ("password", "last_login", "email", "phone", "first_name", "last_name") VALUES ('', '2015-07-13 17:49:25.779534+00:00', 'testJkQS.userUksx@example.com', '', 'testJkQS', 'userUksx') RETURNING "accounts_user"."id"
152 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.382 ms
153 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: INSERT INTO "accounts_customer" ("user_ptr_id", "advisor_id") VALUES (1, NULL)
154 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.199 ms
155 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: RELEASE SAVEPOINT "s140735112696576_x1"
156 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.022 ms
157 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: UPDATE "accounts_user" SET "password" = 'md5$LNepsrK4upi8$400710819735936b83344e0c47836251', "last_login" = '2015-07-13 17:49:25.779534+00:00', "is_superuser" = true, "email" = 'testJkQS.userUksx@example.com', "first_name" = 'testJkQS', "last_name" = 'userUksx' WHERE "accounts_user"."id" = 1
158 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.363 ms
****159 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: UPDATE "accounts_customer" SET "advisor_id" = NULL WHERE "accounts_customer"."user_ptr_id" = 1
160 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.274 ms
161 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  disconnection: session time: 0:00:00.156 user=rex database=test_db host=::1 port=58134
1 (PID: 44080, TID: 0, Host: ) LOG:  connection received: host=::1 port=58135
143 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: BEGIN
145 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: SELECT * FROM "accounts_customer" INNER JOIN "accounts_user" ON ( "accounts_customer"."user_ptr_id" = "accounts_user"."id" ) WHERE "accounts_user"."email" = 'testhTiJ.userRxki@example.com' LIMIT 21
146 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  duration: 1.368 ms
147 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: SAVEPOINT "s140735112696576_x1"
149 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: SELECT (1) AS "a" FROM "accounts_customer" WHERE "accounts_customer"."account_number" = '71017283' LIMIT 1
150 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  duration: 0.198 ms
151 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: INSERT INTO "accounts_user" ("password", "last_login", "email", "phone", "first_name", "last_name",) VALUES ('', '2015-07-13 17:48:01.528782+00:00', 'testhTiJ.userRxki@example.com', '', 'testhTiJ', 'userRxki', ) RETURNING "accounts_user"."id"
152 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.351 ms
153 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  statement: INSERT INTO "accounts_customer" ("user_ptr_id", "advisor_id") VALUES (1, NULL)
154 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.176 ms
155 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  statement: RELEASE SAVEPOINT "s140735112696576_x1"
156 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.033 ms
157 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  statement: UPDATE "accounts_user" SET "password" = 'md5$xN2n3doGJJHs$388f6cf97aa7ddba7c317108a7d4d511', "last_login" = '2015-07-13 17:48:01.528782+00:00', "email" = 'testhTiJ.userRxki@example.com', "first_name" = 'testhTiJ', "last_name" = 'userRxki' WHERE "accounts_user"."id" = 1
158 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.291 ms
159 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  disconnection: session time: 0:00:00.142 user=rex database=test_db host=::1 port=58068
1 (PID: 43833, TID: 0, Host: ) LOG:  connection received: host=::1 port=58069
失败postgres日志:

145 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: SELECT * FROM "accounts_customer" INNER JOIN "accounts_user" ON ( "accounts_customer"."user_ptr_id" = "accounts_user"."id" ) WHERE "accounts_user"."email" = 'testJkQS.userUksx@example.com' LIMIT 21
146 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  duration: 1.927 ms
147 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: SAVEPOINT "s140735112696576_x1"
148 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  duration: 0.041 ms
149 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: SELECT (1) AS "a" FROM "accounts_customer" WHERE "accounts_customer"."account_number" = '87611264' LIMIT 1
150 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  duration: 0.187 ms
151 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  statement: INSERT INTO "accounts_user" ("password", "last_login", "email", "phone", "first_name", "last_name") VALUES ('', '2015-07-13 17:49:25.779534+00:00', 'testJkQS.userUksx@example.com', '', 'testJkQS', 'userUksx') RETURNING "accounts_user"."id"
152 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.382 ms
153 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: INSERT INTO "accounts_customer" ("user_ptr_id", "advisor_id") VALUES (1, NULL)
154 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.199 ms
155 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: RELEASE SAVEPOINT "s140735112696576_x1"
156 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.022 ms
157 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: UPDATE "accounts_user" SET "password" = 'md5$LNepsrK4upi8$400710819735936b83344e0c47836251', "last_login" = '2015-07-13 17:49:25.779534+00:00', "is_superuser" = true, "email" = 'testJkQS.userUksx@example.com', "first_name" = 'testJkQS', "last_name" = 'userUksx' WHERE "accounts_user"."id" = 1
158 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.363 ms
****159 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  statement: UPDATE "accounts_customer" SET "advisor_id" = NULL WHERE "accounts_customer"."user_ptr_id" = 1
160 (PID: 44072, TID: 394680, Host: ::1(58134)) LOG:  duration: 0.274 ms
161 (PID: 44072, TID: 0, Host: ::1(58134)) LOG:  disconnection: session time: 0:00:00.156 user=rex database=test_db host=::1 port=58134
1 (PID: 44080, TID: 0, Host: ) LOG:  connection received: host=::1 port=58135
143 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: BEGIN
145 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: SELECT * FROM "accounts_customer" INNER JOIN "accounts_user" ON ( "accounts_customer"."user_ptr_id" = "accounts_user"."id" ) WHERE "accounts_user"."email" = 'testhTiJ.userRxki@example.com' LIMIT 21
146 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  duration: 1.368 ms
147 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: SAVEPOINT "s140735112696576_x1"
149 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: SELECT (1) AS "a" FROM "accounts_customer" WHERE "accounts_customer"."account_number" = '71017283' LIMIT 1
150 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  duration: 0.198 ms
151 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  statement: INSERT INTO "accounts_user" ("password", "last_login", "email", "phone", "first_name", "last_name",) VALUES ('', '2015-07-13 17:48:01.528782+00:00', 'testhTiJ.userRxki@example.com', '', 'testhTiJ', 'userRxki', ) RETURNING "accounts_user"."id"
152 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.351 ms
153 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  statement: INSERT INTO "accounts_customer" ("user_ptr_id", "advisor_id") VALUES (1, NULL)
154 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.176 ms
155 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  statement: RELEASE SAVEPOINT "s140735112696576_x1"
156 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.033 ms
157 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  statement: UPDATE "accounts_user" SET "password" = 'md5$xN2n3doGJJHs$388f6cf97aa7ddba7c317108a7d4d511', "last_login" = '2015-07-13 17:48:01.528782+00:00', "email" = 'testhTiJ.userRxki@example.com', "first_name" = 'testhTiJ', "last_name" = 'userRxki' WHERE "accounts_user"."id" = 1
158 (PID: 43828, TID: 394672, Host: ::1(58068)) LOG:  duration: 0.291 ms
159 (PID: 43828, TID: 0, Host: ::1(58068)) LOG:  disconnection: session time: 0:00:00.142 user=rex database=test_db host=::1 port=58068
1 (PID: 43833, TID: 0, Host: ) LOG:  connection received: host=::1 port=58069
堆栈跟踪:

======================================================================
ERROR: test_my_test (website.apps.MyApp.tests.test_file.MyTestClass)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../tests/test_file.py", line 33, in test_my_test
    customer1 = accounts_factories.CustomerFactory()
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/factory/base.py", line 81, in __call__
    return cls.create(**kwargs)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/factory/base.py", line 559, in create
    return cls._generate(True, attrs)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/factory/base.py", line 492, in _generate
    cls._after_postgeneration(obj, create, results)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/factory/django.py", line 156, in _after_postgeneration
    obj.save()
  File "/Users/User/pkgs/MyProject/MyProject/website/apps/accounts/models.py", line 198, in save
    return super(Customer, self).save(*args, **kwargs)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/models/base.py", line 589, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/models/base.py", line 617, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/models/base.py", line 679, in _save_table
    forced_update)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/models/base.py", line 723, in _do_update
    return filtered._update(values) > 0
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/models/query.py", line 600, in _update
    return query.get_compiler(self.db).execute_sql(CURSOR)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1005, in execute_sql
    cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 787, in execute_sql
    cursor.execute(sql, params)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/Users/User/pkgs/MyProject/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
DatabaseError: server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.

-------------------- >> begin captured logging << --------------------
factory.generate: DEBUG: BaseFactory: Preparing accounts.factories.CustomerFactory(extra={})
factory.generate: DEBUG: <class 'accounts.factories.CustomerFactory'>: Setting up next sequence (0)
factory.containers: DEBUG: LazyStub: Computing values for accounts.factories.CustomerFactory(first_name=<OrderedDeclarationWrapper for <factory.fuzzy.FuzzyText object at 0x10bf1b350>>, last_name=<OrderedDeclarationWrapper for <factory.fuzzy.FuzzyText object at 0x10bf1b390>>, email=<OrderedDeclarationWrapper for <factory.declarations.LazyAttribute object at 0x10bf1b3d0>>)
factory.generate: DEBUG: LazyAttribute: Evaluating <function <lambda> at 0x10bf1d500> on <LazyStub for accounts.factories.CustomerFactory>
factory.containers: DEBUG: LazyStub: Computed values, got accounts.factories.CustomerFactory(first_name=u'testhTiJ', last_name=u'userRxki', email='testhTiJ.userRxki@example.com')
factory.generate: DEBUG: BaseFactory: Generating accounts.factories.CustomerFactory(first_name=u'testhTiJ', last_name=u'userRxki', email='testhTiJ.userRxki@example.com')
factory.generate: DEBUG: PostGenerationMethodCall: Calling <Customer: testhTiJ.userRxki@example.com>.set_password('secret')
--------------------- >> end captured logging << ---------------------
======================================================================
错误:test\u my\u test(website.apps.MyApp.tests.test\u file.MyTestClass)
----------------------------------------------------------------------
回溯(最近一次呼叫最后一次):
文件“../tests/test\u File.py”,test\u my\u test中的第33行
customer1=帐户\工厂。CustomerFactory()
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/factory/base.py”,第81行,在调用中__
返回cls.create(**kwargs)
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/factory/base.py”,第559行,在create中
返回cls.\u生成(真,属性)
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/factory/base.py”,第492行,在
生成后(obj、创建、结果)的cls.\u
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/factory/django.py”,第156行,在生成后的
obj.save()
文件“/Users/User/pkgs/MyProject/MyProject/website/apps/accounts/models.py”,第198行,保存
返回超级(客户,自我)。保存(*args,**kwargs)
保存中的文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/models/base.py”,第589行
强制更新=强制更新,更新字段=更新字段)
save_base中的文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/models/base.py”,第617行
更新=自我。保存表格(原始、cls、强制插入、强制更新、使用、更新字段)
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/models/base.py”,第679行,在保存表格中
强制更新)
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/models/base.py”,第723行,在更新中
返回已筛选的。\u更新(值)>0
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/models/query.py”,第600行,在更新中
返回query.get_编译器(self.db)。执行_sql(游标)
execute_sql中的文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/models/sql/compiler.py”,第1005行
cursor=super(SQLUpdateCompiler,self)。执行sql(结果类型)
execute_sql中的文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/models/sql/compiler.py”,第787行
cursor.execute(sql,params)
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/backends/utils.py”,执行中第65行
返回self.cursor.execute(sql,params)
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/utils.py”,第94行,在__
6.重新播放(dj_exc_类型、dj_exc_值、回溯)
文件“/Users/User/pkgs/MyProject/lib/python2.7/site packages/django/db/backends/utils.py”,执行中第65行
返回self.cursor.execute(sql,params)
DatabaseError:服务器意外关闭了连接
这可能意味着服务器异常终止
在处理请求之前或期间。

-------------------->>开始捕获日志>结束捕获日志在多个处理器上运行django nose不能很好地处理数据库,或者更准确地说,django事务/数据库连接器

尝试使用此包拆分测试:。检查关于改进Django测试性能的最后一节


此外,Python3.4还包括Sqlite3的改进版本,该版本应该在处理并发性方面更好。YMMV.

谢谢大卫,非常感谢!我今天一直在玩鼻子拾取器,仍然掌握着如何最好地实现它,但它似乎在工作。很高兴听到这个消息。你能投票/接受我的回答吗?:)