Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm using SQLAlchemy with the below User model to track users on my site. I'm trying to get the __init__ method to populate all of the fields in the class instance once it's passed a valid user id, but it doesn't work like it's supposed to.

Here's my code:

class User(db.Model):
    # Fields
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32))
    email = db.Column(db.String(255), index=True)

    # Methods
    def __init__(self, id):
        # Populate the fields
        u = User.query.filter_by(id=id).first()

        # Fill in the name, email fields from the result
        self = u # <-- Not working as expected
    # ...

The problem is that the attributes are not getting populated.

u = User(1)
u.id, u.name, u.email # <-- Output: None

How can I auto-populate all the class attributes from the user id without having to set them one by one?

Note: I've removed the validation bits from the above code to avoid clutter Note2: I'm a beginner in SQLAlchemy, and just recently started using Python.

share|improve this question
2  
Normally in SQLAlchemy, the constructor is used to create a new object, for example to insert into the database, not to load one from the database. Do you have a particular need to do things differently? If you're just looking for a convenient place to define a lookup function, see @Oleh's answer. –  Dan Getz Jun 22 at 15:36
2  
Maybe I should go further and say that in Python in general, a constructor is used for creating a new instance, not for looking up an existing one. Why use a constructor for looking up when you can write functions that are not methods on an already existing instance? (Normal functions, classmethods, staticmethods) –  Dan Getz Jun 22 at 15:52
    
@DanGetz thanks Dan! So I just need to remove it from the constructor, and move it to a "normal" function. That makes perfect sense –  Yazin Jun 22 at 16:06
1  
While it's not the best idea to change constructor semantics, there is an official example of how to do this if you really want. –  davidism Jun 22 at 16:10
add comment

1 Answer

up vote 0 down vote accepted

For this particular case you can use get which gets a row by its primary key:

u = User.get(1)
u.id, u.name, u.email

The problem with your code is that you're trying to use a bound method, even worse, the constructor (in which assigning to self does nothing at all) to get an existing, completely different instance.

I'll just show a reimplementation of the get method so you can reuse it for other cases.

class User(db.Model):
    # ...

    @classmethod
    def get_by_id(cls, id):
        return cls.query.filter_by(id=id).one()


u = User.get_by_id(1)
share|improve this answer
    
Thank Oleh. I'm still unclear on how the model gets updated from within the same class? –  Yazin Jun 22 at 13:41
    
Nothing gets updated, thats the whole point. Read on classmethods. –  Oleh Prypin Jun 22 at 13:42
    
Know a good tutorial that covers the basics? That'd be a lot more useful than an attitude. –  Yazin Jun 22 at 14:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.