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

Problem in auto-jointure #45

Open
FrViPofm opened this issue Jan 4, 2021 · 2 comments
Open

Problem in auto-jointure #45

FrViPofm opened this issue Jan 4, 2021 · 2 comments

Comments

@FrViPofm
Copy link

FrViPofm commented Jan 4, 2021

Hi all,

Using Bottle and Macaron, I try to implement a kind of sponsorship with a self-jointure on the sql table 'user'

CREATE TABLE "user" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,
    "pseudo" TEXT  NOT NULL,
    "sponsor_id" INTEGER  REFERENCES user (id) NOT NULL
    );

The Macaron implementation should be :

class User (macaron.Model):
    pseudo       = macaron.CharField( max_length=32 )
    sponsor_id   = macaron.IntegerField()
    sponsor      = macaron.ManyToOne( User, fkey="sponsor_id", ref_key="id", related_name="godchildren", on_delete="SET NULL", on_update="CASCADE" )

But Traceback returns : NameError: name 'User' is not defined
So, I implement User.sponsor outside the class definition :

User.sponsor      = macaron.ManyToOne( User, fkey="sponsor_id", ref_key="id", related_name="godchildren", on_delete="SET NULL", on_update="CASCADE" )

It works well when I ask : User.get(id).sponsor

But not on : User.get(id).godchildren where I get the Exception : AttributeError("'User' object has no attribute 'godchildren'")

Is it the right way to implement such a jointure ? Is it a bug ? A limitation ?

Thanks in advance.

Have a good year.

nobrin added a commit that referenced this issue May 29, 2021
To define ManyToOne to before defined-model, using str of model name is acceptable.
But in self-relationship is not effectable.
In this fix, self-relationships can be defined with model name string.
@nobrin
Copy link
Owner

nobrin commented May 29, 2021

@FrViPofm Sorry, but my response is too late.

It may be fixed with latest commit.
You can define self-relationships by using the model name.

I verify the behavior.

CREATE TABLE "user" (
    "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,
    "pseudo" TEXT  NOT NULL,
    "sponsor_id" INTEGER  REFERENCES user (id) NOT NULL
    );
import macaron

class User(macaron.Model):
    pseudo = macaron.CharField(max_length=32)
    sponsor_id = macaron.IntegerField(null=True)
    sponsor = macaron.ManyToOne("User", fkey="sponsor_id", ref_key="id", related_name="godchildren", on_delete="SET NULL", on_update="CASCADE")

macaron.macaronage(dbfile="test.db")
sponsor = User.create(pseudo="Sponsor", sponsor_id=1)
user1 = User.create(pseudo="User1", sponsor=sponsor)
macaron.bake()
user1 = User.get(pseudo="User1")
print(user1)
print(user1.sponsor.godchildren)

Result,

<User object 2>
[<User object 1>, <User object 2>]

@FrViPofm
Copy link
Author

Many thanks!
I'll try in few days.

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