0

I'm building a simple app in Flask and having difficulty with making the database behave properly while using Flask-SQLAlchemy. Here's my models.py:

from spot import plate
from spot import db
import flask.ext.whooshalchemy as whooshalchemy

class Country(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    country_name = db.Column(db.String(64), unique = True)
    codes = db.relationship('Code', backref='country', lazy='dynamic')

    def __repr__(self):
        return '<%r>' % (self.country_name)

class Code(db.Model):
    __searchable__ = ['scramble']

    id = db.Column(db.Integer, primary_key = True)
    scramble = db.Column(db.String(64), db.ForeignKey('country.id'))

    def __repr__(self):
        return '<%r>' % (self.scramble)

whooshalchemy.whoosh_index(plate, Code)

I'm trying to create some test data to see if the relationship works as I expect it to, but for some reason, when I create a new Code and commit it to the database, something is overwriting the value of my scramble field to "1", as follows:

>>> from spot.models import Country, Code 
>>> from spot import db
>>> c = Country(country_name="Testingstan")
>>> cd = Code(scramble="TS", country=c)
>>> cd.scramble
'TS'
>>> db.session.add(c)
>>> c.country_name
'Testingstan'
>>> db.session.add(cd)
>>> cd.scramble
'TS'
>>> db.session.commit()
>>> c.country_name
u'Testingstan'
>>> cd.scramble
u'1'
>>> for code in c.codes:
...     print code
...
<u'1'>

So I'm feeling confident that the association between the country and the code is being made properly, but why is SQLAlchemy overwriting my scrambles but not my country name? I pulled up the database in a sqlite database browser, and it's showing me the same thing. What have I set up incorrectly?

1 Answer 1

3

In your Code model you defined the scramble field as your foreign key for the relationship with Country. That makes SQLAlchemy take ownership of the field and use it to store the id of the associated country.

I think what you want is this instead:

class Code(db.Model):
    __searchable__ = ['scramble']

    id = db.Column(db.Integer, primary_key = True)
    scramble = db.Column(db.String(64))
    country_id = db.Column(db.Integer, db.ForeignKey('country.id'))

    def __repr__(self):
        return '<%r>' % (self.scramble)

In this way you get your scramble field to yourself, but you also give SQLAlchemy the foreign key it needs.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.