Django serializer.save()未用PostgreSQL,生产环境报错求助
问题排查:Django定时任务生产环境写入PostgreSQL失败
我有一个通过cronjob自动运行的函数,基于异常检测模型生成预测结果并保存至PostgreSQL数据库:
def prediction_job(): """ This job will run once every batch_minutes minutes to predict if the IPs appear in these batch_minutes minutes are normal or malicious and save the results to postgres """ ip_estimator = IpStatePrediction() predictions = ip_estimator.predict_ip_state() predictions_dict_final = convert_dict_for_serializer(predictions) serializer_result = PredictionsSerializer(data=predictions_dict_final) if serializer_result.is_valid(): serializer_result.save() else: logger.debug("Error with data {}.".format(serializer_result.errors))
本地执行python3 manage.py runserver和python3 migrate --database postgres后,函数可正常保存结果至PostgreSQL;但生产环境执行时出现如下报错:
Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "/usr/local/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute return Database.Cursor.execute(self, query, params) sqlite3.OperationalError: unrecognized token: ":" The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 108, in debug_sql yield File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute return super().execute(sql, params) File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute return self._execute_with_wrappers(sql, params, many=False, executor=self._execute) File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers return executor(sql, params, many, context) File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "/usr/local/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute return Database.Cursor.execute(self, query, params) django.db.utils.OperationalError: unrecognized token: ":" During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view return self.dispatch(request, *args, **kwargs) File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc) File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc) File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, *args, **kwargs) File "/usr/local/lib/python3.8/site-packages/rest_framework/decorators.py", line 50, in handler return func(*args, **kwargs) File "/anomaly_detection/views.py", line 23, in trigger_prediction_cronjob prediction_job() File "/anomaly_detection/access_logs_modeling.py", line 85, in prediction_job serializer_result.save() File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 205, in save self.instance = self.create(validated_data) File "/usr/local/lib/python3.8/site-packages/rest_framework/serializers.py", line 939, in create instance = ModelClass._default_manager.create(**validated_data) File "/usr/local/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 447, in create obj.save(force_insert=True, using=self.db) File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save self.save_base(using=using, force_insert=force_insert, File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base updated = self._save_table( File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 895, in _save_table results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw) File "/usr/local/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert return manager._insert( File "/usr/local/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/usr/local/lib/python3.8/site-packages/django/db/models/query.py", line 1254, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) File "/usr/local/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql cursor.execute(sql, params) File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute return super().execute(sql, params) File "/usr/local/lib/python3.8/contextlib.py", line 131, in __exit__ self.gen.throw(type, value, traceback) File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 113, in debug_sql sql = self.db.ops.last_executed_query(self.cursor, sql, params) File "/usr/local/lib/python3.8/site-packages/django/db/backends/sqlite3/operations.py", line 155, in last_executed_query params = self._quote_params_for_last_executed_query(params) File "/usr/local/lib/python3.8/site-packages/django/db/backends/sqlite3/operations.py", line 144, in _quote_params_for_last_executed_query return cursor.execute(sql, params).fetchone() sqlite3.InterfaceError: Error binding parameter 2 - probably unsupported type.
排查思路与解决方案
1. 数据库连接配置错误(核心问题)
报错明确出现sqlite3.OperationalError,说明生产环境的Django实际在连接SQLite而非PostgreSQL:
- 检查生产环境
settings.py的DATABASES配置,确认PostgreSQL的参数正确,是否将其设为默认数据库;若未设为默认,需在保存时显式指定数据库:serializer_result.save(using='postgres')。 - 确认定时任务启动时加载了正确的配置文件,避免默认使用SQLite配置。
2. 数据类型不兼容
第二个报错提示存在SQLite无法识别的参数类型,需排查数据格式:
- 打印
predictions_dict_final的内容,对比PredictionsSerializer及对应模型的字段定义,确保所有字段类型匹配(比如将numpy的int64转为Python原生int,datetime对象符合Django日期字段要求)。 - 检查
convert_dict_for_serializer函数的逻辑,确认其输出的字典值都是Django模型支持的类型。
3. 生产环境迁移验证
确保生产环境已同步PostgreSQL的表结构:
- 执行
python3 manage.py migrate --database postgres,确认所有模型变更已应用到PostgreSQL,避免因表结构缺失或字段不匹配导致写入失败。
4. 定时任务上下文初始化
cronjob运行时可能未加载完整Django上下文,导致数据库配置未初始化:
- 在定时任务脚本开头添加初始化代码:
import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', '你的项目名.settings') django.setup()
内容的提问来源于stack exchange,提问作者Kosmylo
相关产品推荐
相关产品推荐

