ponyorm / pony

Pony Object Relational Mapper
Apache License 2.0
3.64k stars 245 forks source link

AttributeError: _session_cache_ #602

Open SharkyRawr opened 3 years ago

SharkyRawr commented 3 years ago

I have a problem with how my relationships work (instant rimshot). Maybe I'm not supposed to init the classes in quite this way? I'm confused by the error.

from pony.orm import *

db = Database()

class Menu(db.Entity):
    name = Required(str)
    price = Required(float)
    id = PrimaryKey(str)
    description = Required(str)
    category = Required("MenuCategory")

    def __init__(self, category, pr, *args, **kwargs):
        if type(pr) is str:
            raise Exception('got a string but expected a dict :( -> ' + pr)
        name = pr['nm']
        price = float(pr['pc'])
        id = pr['id']
        description = pr['ds']

        super().__init__(category=category, name=name, price=price, id=id, description=description, *args, **kwargs)

class MenuCategory(db.Entity):
    image_url = Required(str)
    id = PrimaryKey(str)
    name = Required(str)
    menus = Set(Menu)
    restaurant = Required("Restaurant")

    def __init__(self, restaurant, ct, *args, **kwargs):
        menus = []
        image_url = ct['cti']
        id = ct['id']
        name = ct['nm']

        if '0' not in ct['ps']['pr']:
            print('no 0')
            menus += [Menu(self, d) for d in ct['ps']['pr']]
        else:
            print('has 0')
            menus += [Menu(self, d) for d in ct['ps']['pr'].values()]

        super().__init__(restaurant=restaurant, image_url=image_url, id=id, name=name, menus=menus, *args, **kwargs)

class Restaurant(db.Entity):
    name = Required(str)
    address = Required(str)
    lat = Required(float)
    lon = Required(float)
    menu = Set(MenuCategory)

    @db_session
    def __init__(self, json: dict, *args, **kwargs):
        rd = json['rd']
        ad = rd['ad']
        address = f"{ad['st']} {ad['pc']}, {ad['tn']}"
        menus = [MenuCategory(self, m) for m in rd['mc']['cs']['ct']]
        super().__init__(name=rd['nm'],
            address=address, lat=ad['lt'],
            lon=ad['ln'],
            menu=menus
        *args, **kwargs)

db.bind(provider='sqlite', filename='database.sqlite', create_db=True)
db.generate_mapping(create_tables=True)

Using it like this from a different file:

with db_session:
    res = Restaurant(r)

r = json dictionary http response

The error I get:

$ python fetch.py
no 0
Traceback (most recent call last):
  File "C:\Users\Sharky\Desktop\lieferando\fetch.py", line 17, in <module>
    res = Restaurant(r)
  File "<string>", line 2, in __init__
  File "C:\Python39\lib\site-packages\pony\orm\core.py", line 520, in new_func
    return func(*args, **kwargs)
  File "C:\Users\Sharky\Desktop\lieferando\db.py", line 72, in __init__
    menus = [MenuCategory(self, m) for m in rd['mc']['cs']['ct']]
  File "C:\Users\Sharky\Desktop\lieferando\db.py", line 72, in <listcomp>
    menus = [MenuCategory(self, m) for m in rd['mc']['cs']['ct']]
  File "C:\Users\Sharky\Desktop\lieferando\db.py", line 45, in __init__
    menus += [Menu(self, d) for d in ct['ps']['pr']]
  File "C:\Users\Sharky\Desktop\lieferando\db.py", line 45, in <listcomp>
    menus += [Menu(self, d) for d in ct['ps']['pr']]
  File "C:\Users\Sharky\Desktop\lieferando\db.py", line 20, in __init__
    super().__init__(category=category, name=name, price=price, id=id, description=description, *args, **kwargs)
  File "C:\Python39\lib\site-packages\pony\orm\core.py", line 4712, in __init__
    avdict[attr] = attr.validate(val, obj, from_db=False)
  File "C:\Python39\lib\site-packages\pony\orm\core.py", line 2544, in validate
    val = Attribute.validate(attr, val, obj, entity, from_db)
  File "C:\Python39\lib\site-packages\pony\orm\core.py", line 2232, in validate
    if cache is not val._session_cache_:
AttributeError: _session_cache_

I hope someone can make sense of this. 😕

SharkyRawr commented 3 years ago

Figured it out using PyDev, was mixing transactions. No clue why it gave an error about the session cache.