Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function as insert value #1680

Open
DTS-And-Eaglepoint-Funding opened this issue Jul 24, 2024 · 1 comment
Open

Function as insert value #1680

DTS-And-Eaglepoint-Funding opened this issue Jul 24, 2024 · 1 comment

Comments

@DTS-And-Eaglepoint-Funding
Copy link

DTS-And-Eaglepoint-Funding commented Jul 24, 2024

im trying to convert this code to tortoise

table = Table('linkedin_logging')

q = MySQLQuery.into(table).columns(
    table.date, table.withdraw, table.connections, table.whatsapp, table.like
).insert(
    CurDate(), 0, 1, 0, 0
).on_duplicate_key_update(
    table.connections, table.connections + 1
)

date is a unique

this is the table sql

CREATE TABLE `linkedin_logging` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `date` date NOT NULL,
  `withdraw` bigint(20) NOT NULL DEFAULT 0,
  `connections` bigint(20) NOT NULL DEFAULT 0,
  `whatsapp` bigint(20) NOT NULL DEFAULT 0,
  `like` bigint(20) NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY `linkedin_logging_date_unique` (`date`)
) ENGINE=InnoDB AUTO_INCREMENT=478747 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

whenever i run it i get

Traceback with variables (most recent call last):
  File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/models.py", line 1140, in create
    instance = cls(**kwargs)
      cls = <class 'models.models.LinkedinLogging'>
      using_db = None
      kwargs = {'withdraw': 1, 'date': <pypika.functions.CurDate object at 0x79541ad1c790>}
  File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/models.py", line 660, in __init__
    for key in meta.fields.difference(self._set_kwargs(kwargs)):
      self = <exception while printing> Traceback (most recent call last):
          File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/traceback_with_variables/core.py", line 222, in _to_cropped_str
            raw = print_(obj)
          File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/models.py", line 767, in __repr__
            if self.pk:
          File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/models.py", line 784, in _get_pk_val
            return getattr(self, self._meta.pk_attr)
        AttributeError: 'LinkedinLogging' object has no attribute 'id'
        
      kwargs = {'withdraw': 1, 'date': <pypika.functions.CurDate object at 0x79541ad1c790>}
      meta = <tortoise.models.MetaInfo object at 0x79541af5e980>
  File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/models.py", line 696, in _set_kwargs
    setattr(self, key, field_object.to_python_value(value))
      self = <exception while printing> Traceback (most recent call last):
          File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/traceback_with_variables/core.py", line 222, in _to_cropped_str
            raw = print_(obj)
          File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/models.py", line 767, in __repr__
            if self.pk:
          File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/models.py", line 784, in _get_pk_val
            return getattr(self, self._meta.pk_attr)
        AttributeError: 'LinkedinLogging' object has no attribute 'id'
        
      kwargs = {'withdraw': 1, 'date': <pypika.functions.CurDate object at 0x79541ad1c790>}
      meta = <tortoise.models.MetaInfo object at 0x79541af5e980>
      passed_fields = {'withdraw', 'date'}
      key = 'date'
      value = <pypika.functions.CurDate object at 0x79541ad1c790>
      field_object = <tortoise.fields.data.DateField object at 0x79541acc33a0>
  File "/home/dell/Desktop/bot_sqlV4/tortoise/venv/lib/python3.10/site-packages/tortoise/fields/data.py", line 408, in to_python_value
    value = parse_datetime(value).date()
      self = <tortoise.fields.data.DateField object at 0x79541acc33a0>
      value = <pypika.functions.CurDate object at 0x79541ad1c790>
builtins.TypeError: argument must be str
@waketzheng
Copy link
Contributor

waketzheng commented Nov 19, 2024

You can do it this way:

from __future__ import annotations

import datetime

from tortoise import Model, fields, run_async
from tortoise.contrib.test import init_memory_sqlite


class LinkedinLogging(Model):
    class Meta:
        table = "linkedin_logging"

    id = fields.IntField(pk=True)
    date = fields.DateField(unique=True)
    withdraw = fields.IntField(default=0)
    connections = fields.IntField(default=0)
    whatsapp = fields.IntField(default=0)
    like = fields.IntField(default=0)

    @classmethod
    async def get_no_duplicate_value(cls, field: str, value: int) -> int:
        already: list[int] = (
            await LinkedinLogging.filter(**{f"{field}__gte": value})  # type:ignore[assignment]
            .order_by(field)
            .values_list(field, flat=True)
        )
        if not already:
            return value
        for avail, used in zip(range(value, len(already) + value + 1), already):
            if avail != used:
                return avail
        else:
            return used + 1


@init_memory_sqlite
async def main():
    columns = "table.withdraw, table.connections, table.whatsapp, table.like"
    cols = [i.split(".")[-1] for i in columns.split(",")]
    values = [0, 1, 0, 0]
    data = dict(zip(cols, values))
    today = datetime.date.today()

    field = "connections"
    data[field] = await LinkedinLogging.get_no_duplicate_value(field, data[field])
    obj = LinkedinLogging(date=today, **data)
    await obj.save()
    print(dict(obj))
    # {'connections': 1, ...}

    data[field] = await LinkedinLogging.get_no_duplicate_value(field, data[field])
    obj2 = LinkedinLogging(date=today + datetime.timedelta(1), **data)
    await obj2.save()
    print(dict(obj2))
    # {'connections': 2, ...}

    data[field] = await LinkedinLogging.get_no_duplicate_value(field, data[field])
    obj3 = LinkedinLogging(date=today + datetime.timedelta(2), **data)
    await obj3.save()
    print(dict(obj3))
    # {'connections': 3, ...}


run_async(main())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants