Django - deterministic=True 在运行 python manage.py runserver 时需要 SQLite 3.8.3 或更高版本。

26

我正在AWS上运行一个Linux Red Hat环境。

我已经按照每个指示升级sqlite3到“最新”版本。

我正在运行Python 3.9.2(并已重新编译它,使用LD_RUN_PATH=/usr/local/lib ./configure),以及Django版本4。

我已经设置了一个虚拟环境来安装和运行Django。我已经更改了激活脚本以包括export LD_LIBRARY_PATH="/usr/local/lib"

在运行python manage.py runserver时,我收到错误消息django.db.utils.NotSupportedError: deterministic=True requires SQLite 3.8.3 or higher。我已经打开了文件/home/ec2-user/django/django/db/backends/sqlite3/base.py(发生错误的位置)并在错误所在行之后添加了一个打印语句:

print("**************************\n" +
    str(Database.sqlite_version) +
    "\n" + str(Database.sqlite_version_info) +
    "\n**************************")

返回:

**************************
3.28.0
(3, 28, 0)
**************************
**************************
3.28.0
(3, 28, 0)
**************************

请告诉我还需要哪些额外信息。我在 stack 上下搜索,无法找到正确的解决方法来弹出这个问题。

提前致谢!

编辑:

以下是追踪信息:

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/home/ec2-user/django/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/home/ec2-user/django/django/utils/asyncio.py", 21 in inner
    return func(*args, **kwargs)
  File "/home/ec2-user/django/django/db/backends/base/base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/ec2-user/django/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/ec2-user/django/django/db/backends/sqlite3/base.py", line 210, in get_new_connection
    create_deterministic_function('django_date_extract', 2, _sqlite_datetime_extract)
sqlite3.NotSupportedError: deterministic=True requires SQLite 3.8.3 or higher

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/opt/python/lib/python/3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/opt/python39/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/home/ec2-user/django/django/utils/autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "/home/ec2-user/django/django/core/management/commands/runserver.py", line 126, in inner_run
    self.check_migrations()
  File "/home/ec2-user/django/django/core/management/base.py", line 486, in check_migrations
    executor = MigrationExecutor(connectsion[DEFAULT_DB_ALIAS])
  File "/home/ec2-user/django/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
  File "/home/ec2-user/django/django/db/migrations/loader.py", line 53, in __init__
    self.build_graph()
  File "/home/ec2-user/django/django/db/migrations/loader.py", line 220, in build_graph
    self.applied_migrations = recorder.applied_migrations()
  File "/home/ec2-user/django/django/db/migrations/recorder.py", line 77, in applied_migrations
    if self.has_table():
  File "/home/ec2-user/django/django/db/migrations/recorder.py", line 55, in has_table
    with self.connection.cursor() as cursor:
  File "/home/ec2-user/django/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/ec2-user/django/django/db/backends/base/base.py", line 259, in cursor
    return self._cursor()
  File "/home/ec2-user/django/django/db/backends/base/base.py", line 235, in _cursor
    self.ensure_connection()
  File "/home/ec2-user/django/djanog/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/ec2-user/django/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/home/ec2-user/django/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/ec2-user/django/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/home/ec2-user/django/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/ec2-user/django/django/db/backends/base/base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/home/ec2-user/django/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/home/ec2-user/django/django/db/backends/sqlite3/base.py", line 210, in get_new_connection
    create_deterministic_function('django_date_extract', 2, _sqlite_datetime_extract)
django.db.utils.NotSupportedError: deterministic=True requires SQLite 3.8.3 or higher
6个回答

21

我在我的Linux Centos7+Python 3.9.6+Django 3.2.5中遇到了同样的问题。虽然SQLite3已经更新到最新版本,但似乎没有用。一种解决方法是将数据库从SQLite3更改为pysqlite3。激活虚拟环境后,安装pysqlite。

pip3 install pysqlite3
pip3 install pysqlite3-binary

并在base.py中更改数据库

vim python3.9.6/site-packages/django/db/backends/sqlite3/base.py

# from sqlite3 import dbapi2 as Database # annotation
from pysqlite3 import dbapi2 as Database # import pysqlite3

重启 Django 服务器,它就可以工作了。


1
这不是基本答案,但工作得非常好。谢谢。 - hn_tired
在运行“pip3 install pysqlite3”时出现了以下错误 -> 致命错误C1083:“sqlite3.h”:没有那个文件或目录。 - Tomás Gomez Pizarro
@TomásGomezPizarro 这可能是pip或您的Python解释器出了问题。您可能需要删除并重新安装Python。 - Shmack

5

可以通过使用正确的环境重新编译Python3来解决此问题。以下是重新编译Python3的命令。

export C_INCLUDE_PATH=/PATH_TO_SQLITE/include
export CPLUS_INCLUDE_PATH=/PATH_TO_SQLITE/include 
export LD_RUN_PATH=/PATH_TO_SQLITE/lib
./configure --prefix=/PATH_FOR_PYTHON 
make
make install

接下来可以通过以下命令在Python中进行检查:

import sqlite3 
conn = sqlite3.connect(':memory:') 
conn.create_function('f', 2, lambda *args: None, deterministic=True) 

我需要一段时间才能测试这个,所以我会点赞,因为这似乎是直观的答案。虽然我在帖子中提到我已经重新编译了,但我可能没有在这之前导出变量或包含Python路径。 - Shmack
确认这对我来说是完美的解决方案。(CentOS 7,手动更新:python3.9,sqlite3.40)。因为,在线上大多数针对此问题的解决方案都提到了将LD_RUN_PATH设置为静态链接sqlite3,但没有人提到您必须使用C_INCLUDE_PATH和CPLUS_INCLUDE_PATH包含头文件。谢谢。@Jaebak Kim - user1835157

5

enter image description here

我遇到了和你一样的问题,当我尝试在Elastic Beanstalk上部署时。我的情况是这样的:当我像这样初始化EB CLI时,使用了Python 3.8:(原文保留)
eb init -p python-3.8 django-project ⛔

这不是在64位Amazon Linux 2(默认情况下)上运行的良好Python版本。请更改为python-3.7。

eb init -p python-3.7 django-project ✅

1
问题在于我希望保持Python更新。 - Shmack
3
如果你使用的是 Django 4,这个答案将不起作用(需要 Python 3.8+)。 - Caleb

2
目前最好的解决方法是进入/home/ec2-user/django/django/db/backends/sqlite3/base.py,将get_new_connection()函数中的变量deterministic=True改为deterministic=False...
这样可以消除错误,但似乎是一种超级欺骗性的解决方案。如果有更好的修复方法,请告诉我。

这真的有效。天啊,我卡在这里好几天了...我知道这很可疑,但是...我会做更多的研究。我所有的注意力都放在了错误的方向上。我以为是sqlite3版本的问题。 - user1835157
@user1835157 嗯,这肯定存在问题。1. 没有重新做这个,你无法升级django。2. 我不知道它是否会破坏django模型,但很可能会。3. 如果django模型被破坏,你可能无法使用celery(一个与django常用的库)。4. 在安装sqlite3后重新编译python似乎应该可以工作,并且是客观最佳方案 -> @JaebakKim的答案。 - Shmack
1
再次感谢您的提醒。我只是为了学习和测试而这样做。在尝试了您的解决方案后,我继续尝试其他方法。您说得对,重新编译并使用正确的包含和链接选项可能是正确的方式。 - user1835157

0

使用PostgreSQL是一个不错的选择,因为它支持Python 3.8并解决了这个错误。此外,正如在问题中解释的那样,最好在生产环境中使用PostgreSQL。话虽如此,我推荐这个教程,它教你如何在eb上运行postgres。尽管它有点过时,但对我非常有用。


EB在另一个答案中提到了,但很高兴你让它工作了。 - Shmack

-3

安装 pip3 install pysqlite3 打开文件 /usr/local/python3/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py,找到 from sqlite3 import dbapi2 as Database 注释掉,替换为 from pysqlite3 import dbapi2 as Database。

使用 vim /u01/apps/python3/lib/python3.10/site-packages/django/db/backends/sqlite3/_functions.py 命令,将 deterministic=True 参数中的函数变量 get_new_connection() 更改为 deterministic=False。然后保存退出。

接下来,使用 vim /u01/apps/python3/lib/python3.10/site-packages/django/db/backends/base/base.py 命令打开文件,在 def check_database_version_supported 方法里注释掉原有代码,写上 pass。

示例:

def check_database_version_supported(self):
    pass
    """
    如果此版本的 Django 不支持数据库版本,则引发错误。
    """

目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何编写好答案的更多信息。 - Community
是的,我们需要您澄清您的答案,并尝试修复格式。 - Shmack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接