首页 > 解决方案 > Django OperationalError:解析器堆栈溢出

问题描述

我的项目中有一个会计应用程序的多页表单。第一个页面允许用户选择多个债权人,第二个页面允许用户选择多个债务人,第三个页面生成一个表格,以便他们可以输入每个债务人对每个债权人的信用。

表单的每一页通过 POST(使用相关帐户的 UUID)将选定的数据传递到下一页,最后一页有“提交”按钮,该按钮实际在数据库中生成事务对象。

当我使用选择了大量债务人或债权人的表单时,我收到“OperationalError: Parser Stack Overflow”。

从我能找到的关于这个主题的唯一其他问题(django.db.utils.OperationalError: parser stack overflow)看来我需要找到一种更精简的方式来传输该数据(也许通过在数据库来保存来自每个页面的数据,以便每个页面只需要传递一个对象)。但是,正如您从下面的错误中看到的那样,导致溢出的是“account_list”。此列表来自查询:

Account.objects.all().order_by('type')

所以我不确定这是否能解决问题。

或者,我可以增加 SQL 解析器堆栈大小。但是,我无法在我的主机系统上重新编译 sqlite,因为它使用虚拟主机并且我不是系统管理员。

有什么建议么?

来自 django 调试页面的“本地变量”数据如下:

__class__   

<class 'Bank.views.CreateTransactionData'>

account     

<Account: (User) User Z>

account_list    

Error in formatting: OperationalError: parser stack overflow

all_accounts    

<QuerySet [<Account: (User) User A>, <Account: (User) User B>, <Account: (User) User C>, <Account: (User) User D>, <Account: (User) User E>, <Account: (User) User F>, <Account: (User) User G>, <Account: (User) User H>, <Account: (User) User I>, <Account: (User) User J>, <Account: (User) User K>, <Account: (User) User L>, <Account: (User) User M>, <Account: (User) User N>, <Account: (User) User O>, <Account: (User) User P>, <Account: (User) User Q>, <Account: (User) User R>, <Account: (User) User S>, <Account: (User) User T>, '...(remaining elements truncated)...']>

args    

()

creditor    

<Account: (User) User A>

data    

{'0497dfe8-37c5-4939-8dd9-b9c8093d0ae1': 'TRUE',
 '07dbb8d3-cc1f-497f-ab3b-4a5d815cac3a': 'TRUE',
 '0957bfcd-7c16-4559-8e23-57a057c36155': 'TRUE',
 '26fed283-450b-4fe3-8ac6-84dadd67e950': 'TRUE',
 '3129ffe8-0ece-4576-afed-00eeb789ad80': 'TRUE',
 '517ca471-bf9a-40c6-9988-b773da21d30d': 'TRUE',
 '51f4a86f-b5d8-4910-b338-b461c544016d': 'TRUE',
 '5706826c-c895-4063-823f-2d98fdb012ff': 'TRUE',
 '57baa54a-670a-4310-baf3-5bd0023f96a4': 'TRUE',
 '61b91670-5424-4625-a964-8dd257524ee4': 'TRUE',
 '6ae151ff-4e5d-4972-b6a5-16efd819c53b': 'TRUE',
 '6cfecce8-95b2-468c-80d6-b52af2ed2037': 'TRUE',
 '714c8d14-bc4d-47ad-9fae-88366064ade8': 'TRUE',
 '79168ba9-f187-404f-968a-c9224d570d3b': 'TRUE',
 '9d47c7dc-cf6c-4090-a40b-f7c85eaccc37': 'TRUE',
 '9fd1e279-1b70-4ef1-8b79-98ba3d668542': 'TRUE',
 'a1a11ebe-b5d5-49bf-a60f-4f33dafdc5a7': 'TRUE',
 'a5909c0b-d991-4b0e-bb58-ccef7dbdf32f': 'TRUE',
 'a8d74160-50bd-48ce-9862-ba48be6a4619': 'TRUE',
 'b66ed030-d40b-413e-83ec-47082d3281c9': 'TRUE',
 'ca50f233-8118-4e1f-a951-c6a38bd3f285': 'TRUE',
 'creditor': 'a8d74160-50bd-48ce-9862-ba48be6a4619',
 'csrfmiddlewaretoken': 'DwbBCOSdTpV2HhZYgCodQBpF3Ut167EAUfVc8f8AOA04PKTVI4vyn1crFwpSfTGd',
 'd3040f2c-edd1-4466-878e-23aaed0e35e3': 'TRUE',
 'd660841d-1268-4a6a-8b30-5d9cc8157989': 'TRUE',
 'date': '2019-08-29',
 'e4032076-98a7-4a4b-bfc4-d7d599056a77': 'TRUE',
 'ee6880aa-dc23-4827-8598-c6a67766af61': 'TRUE',
 'f0182a4c-c221-45d1-95ac-dd2012111402': 'TRUE'}

date    

datetime.datetime(2019, 8, 29, 0, 0)

key     

UUID('714c8d14-bc4d-47ad-9fae-88366064ade8')

kwargs  

{}

request     

<WSGIRequest: POST '/Bank/Transaction/Create/Data/'>

self    

<Bank.views.CreateTransactionData object at 0x053836D0>

标签: pythonsqldjango

解决方案


整理好了!

对于遇到此问题的其他任何人,问题在于我提取所选帐户列表的方式。

我有:

        # extract list of debtors
        all_accounts = Account.objects.all()
        account_list = Account.objects.none()
        for account in all_accounts:
            key = account.account_key
            if str(key) in data.keys() and data.get(str(key)) == 'TRUE':
                account_list = account_list.union(all_accounts.filter(account_key=key))
        if not account_list.first(): # Check for no debtors selected
            raise Http404('You must have debtors in your transaction.') # Complain

它为您选择的每个帐户创建了一个新查询...

将其更改为:

        # extract list of debtors
        all_accounts = Account.objects.all().order_by('type')
        account_list = []
        for account in all_accounts:
            key = account.account_key
            if str(key) in data.keys() and data.get(str(key)) == 'TRUE':
                account_list.append(account)
        if not account_list: # Check for no debtors selected
            raise Http404('You must have debtors in your transaction.') # Complain

故事的寓意:小心使用 .union() 方法......并且在尝试从头开始构建会计系统之前,可能会参加一些 CS 讲座。


推荐阅读