Flask SQlAlchemy

  • sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'weather_detail.basic_id' could not find table 'weatherbasic' with which to generate a foreign key to target column 'id'

the table name is automatically set for you unless overridden. It’s derived from the class name converted to lowercase and with “CamelCase” converted to “camel_case”.

Define table

  1. Define a table
  2. Define columns: Integer, String, Boolean, Datetime
  3. Constriction: unique, nullable
  4. Add default value
class CurrentBasic(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    location = db.Column(db.String(50), nullable=False)
    description = db.Column(db.String(50), nullable=False)
    icon = db.Column(db.String(10), nullable=False)
    temperature = db.Column(db.Integer, nullable=False)
    temp_unit = db.Column(db.String(10), nullable=False)
    dt = db.Column(db.DateTime, nullable=False)
    amendment = db.Column(db.Boolean, nullable=False, default=False)
    last_update = db.Column(db.DateTime, nullable=False)

def __init__(self, session_id, location, description, icon, temperature, temp_unit, dt):
     self.location = location
     self.description = description
     self.icon = icon
     self.temperature = temperature
     self.temp_unit = temp_unit
     self.dt = dt
     self.last_update = datetime.now()

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

PickleType

PickleType holds Python objects, which are serialized using pickle. For example, here I use PickleType to store a list.

class Daily(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    location = db.Column(db.String(50), nullable=False)
    temp_unit = db.Column(db.String(10), nullable=False)
    daily_list = db.Column(db.PickleType, nullable=False)
    last_update = db.Column(db.DateTime, nullable=False)

Foreign Key & One to One Relationship

  1. uselist=False means this is a one to one relationship
  2. one to one relationship can not set lazy='dynamic'
class CurrentBasic(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    location = db.Column(db.String(50), nullable=False)
    detail = db.relationship('CurrentDetail', backref=db.backref('basic'), uselist=False)


class CurrentDetail(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    basic_id = db.Column(db.Integer, db.ForeignKey('current_basic.id'))

Exception:

* sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'weather_detail.basic_id' could not find table 'weatherbasic' with which to generate a foreign key to target column 'id'

Root cause:

The table name is automatically set for you unless overridden. It’s derived from the class name converted to lowercase and with “CamelCase” converted to “camel_case”.

So, change db.ForeignKey('currentbasic.id') to db.ForeignKey('current_basic.id')

Query, filter

  1. filter_by
    detail = CurrentDetail.query.filter_by(basic_id=basic.id).first()
    
  2. fileter
    from sqlalchemy import and_
    condition = and_(CurrentBasic.session_id == self.session_id, CurrentBasic.location == self.location)
    basic = CurrentBasic.query.filter(condition).first()
    
  3. filter all
    history_basic = HistoryBasic.query.filter_by(session_id=self.session_id).all()
    

Insert

basic = CurrentBasic(current['location'],
                     current['description'],
                     current['icon'],
                     current['temperature'],
                     current['temp_unit'],
                     current['datetime'])
db.session.add(basic)
db.session.commit()
  • Insert to a table with foreign key
    detail = CurrentDetail(current['pressure'],
                           current['humidity'],
                           current['wind_direction'],
                           current['wind_speed'],
                           current['wind_unit'],
                           current['clouds'],
                           current['sunrise'],
                           current['sunset'],
                           current['rain'],
                           current['snow'],
                           basic)
    db.session.add(detail )
    db.session.commit()
    

Update

basic.description = current['description']
basic.icon = current['icon']
basic.temperature = current['temperature']
basic.temp_unit = current['temp_unit']
basic.dt = current['datetime']
basic.last_update = datetime.now()
db.session.commit()

Import json file to database

# load weather description
def load_description():
    with open('description.json', encoding='utf-8') as file:
        text = file.readlines()
        for line in text:
            data = json.loads(line)
            record = Description(data['desc_id'], data['group'],
                                 data['description'])
            db.session.add(record)
            db.session.commit()

Configuration

config.py

import os

BASE_DIR = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'weather.db')
SQLALCHEMY_TRACK_MODIFICATIONS = True

results matching ""

    No results matching ""