djongo.exceptions.SQLDecodeError trying to create model object

Viewed 31

I have the following stripped down view that is giving strange error:

def main_dividends_results(request, ticker, dividends_years_back, earnings_years_back):

    now = datetime.datetime.now()
    stock, created = StockInfo.objects.get_or_create(ticker=ticker)

    # return HttpResponse("worked")

    if created:
        logger.warning("stock {ticker} didnt exist in db".format(ticker=ticker))
        yahoo_stock_obj = yfinance.Ticker(ticker.upper())
        earnings_history = yahoo_stock_obj.earnings_history
        save_stock_info_data(yahoo_stock_obj, ticker, stock, earnings_history)
        logger.warning("stock {ticker} saved".format(ticker=ticker))

I get error

[2022-09-14 00:05:00 +0000] [17741] [DEBUG] GET /dividends/TD/3/5
Internal Server Error: /dividends/TD/3/5
Traceback (most recent call last):
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/query.py", line 573, in get_or_create
    return self.get(**kwargs), False
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/query.py", line 429, in get
    raise self.model.DoesNotExist(
dividends_info.models.StockInfo.DoesNotExist: StockInfo matching query does not exist.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/cursor.py", line 51, in execute
    self.result = Query(
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 784, in __init__
    self._query = self.parse()
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 876, in parse
    raise e
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 857, in parse
    return handler(self, statement)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 928, in _insert
    query = InsertQuery(self, self.db, self.connection_properties, sm, self._params)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 340, in __init__
    super().__init__(*args)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 62, in __init__
    self.parse()
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 410, in parse
    self._fill_values(statement)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/sql2mongo/query.py", line 368, in _fill_values
    raise SQLDecodeError
djongo.exceptions.SQLDecodeError: 

    Keyword: None
    Sub SQL: None
    FAILED SQL: ('INSERT INTO "dividends_info_stockinfo" ("ticker", "current_price", "name", "summary", "sector", "dividends", "earnings", "last_updated_time") VALUES (%(0)s, %(1)s, %(2)s, %(3)s, %(4)s, %(5)s, %(6)s, %(7)s)',)
    Params: (['TD', None, None, None, None, None, None, datetime.datetime(2022, 9, 14, 0, 5, 1, 728721)],)
    Version: 1.3.6

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

Traceback (most recent call last):
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/cursor.py", line 59, in execute
    raise db_exe from e
djongo.database.DatabaseError

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

Traceback (most recent call last):
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/root/stocks_backend/dividends_info/views.py", line 33, in main_dividends_results
    stock, created = StockInfo.objects.get_or_create(ticker=ticker)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/query.py", line 576, in get_or_create
    return self._create_object_from_params(kwargs, params)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/query.py", line 610, in _create_object_from_params
    obj = self.create(**params)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/query.py", line 447, in create
    obj.save(force_insert=True, using=self.db)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/base.py", line 753, in save
    self.save_base(using=using, force_insert=force_insert,
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/base.py", line 790, in save_base
    updated = self._save_table(
  File "/root/stocks_backend/stocks-env/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 "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/base.py", line 933, in _do_insert
    return manager._insert(
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/root/stocks_backend/stocks-env/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 "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql
    cursor.execute(sql, params)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/root/stocks_backend/stocks-env/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 "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/root/stocks_backend/stocks-env/lib/python3.8/site-packages/djongo/cursor.py", line 59, in execute
    raise db_exe from e
django.db.utils.DatabaseError

I don't understand the issue because all the model fields allow null:

from djongo import models


class Dividend(models.Model):
    date = models.DateField()
    amount = models.FloatField()

    class Meta:
        abstract = True


class Earning(models.Model):
    date = models.DateField()
    expected = models.CharField(max_length=100)
    actual = models.CharField(max_length=100)
    surprise = models.CharField(max_length=10)

    class Meta:
        abstract = True


class StockInfo(models.Model):
    id = models.BigAutoField(primary_key=True)
    ticker = models.CharField(max_length=100, unique=True)
    current_price = models.FloatField(null=True)
    name = models.CharField(max_length=255, null=True)
    summary = models.TextField(null=True)
    sector = models.CharField(max_length=100, null=True)
    dividends = models.ArrayField(model_container=Dividend, null=True)
    earnings = models.ArrayField(model_container=Earning, null=True)
    last_updated_time = models.DateTimeField(null=True, auto_now=True)

    objects = models.DjongoManager()

The worst part is running the exact same code from my test script works! and the database now has exactly 1 StockInfo object:

import json, time, yfinance

import django
django.setup()

from dividends_info.functions.stock_info import save_stock_info_data
from dividends_info.models import StockInfo

import sys

ticker = sys.argv[1]


def update_a_stock(ticker):
    stock, created = StockInfo.objects.get_or_create(ticker=ticker)
    # yahoo_stock_obj = yfinance.Ticker(ticker.upper())
    # earnings_history = yahoo_stock_obj.earnings_history
    # # dividends = yahoo_obj.dividends
    # save_stock_info_data(yahoo_stock_obj, ticker, stock, earnings_history)
    # print(earnings_history)
    # print(stock.dividends[-10:])
    # print(stock.earnings[:10])
    # # if not stock.earnings:
    # #     print(f"No earnings for {ticker}")
    # #     print(stock.earnings)
    # #     # time.sleep(2)
    # #     # print(earnings_history)
    # #     # time.sleep(5)
    # # else:
    # #     print(f"stock earnings length: {len(stock.earnings)}")
    # time.sleep(3)



if __name__ == '__main__':
    update_a_stock(ticker)

Local works fine, I did not make any breaking changes because the same exact code on my local works

bs4
django==3.1.12
django-cors-headers
djongo
gunicorn
html5lib
pymongo==3.12.3
python-decouple
sqlparse==0.2.4
yfinance

I don't remember making any breaking changes and my view used to work for weeks now. How can I get the get_or_create to just return an empty StockInfo object?

0 Answers
Related