I have this code which currently lets me update a school's data in mySQL database, if the id already exists. However, what I am also trying to achieve, is that if the ID doesn't exist in the DB, it inserts those values. Here is the code I've got so far:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@localhost/dbName'
db = SQLAlchemy(app)
class Example(db.Model):
__tablename__ = 'schools'
_id = db.Column('_id', db.Unicode, primary_key=True)
establishmentNumber = db.Column('establishmentNumber', db.Unicode)
def __init__(self, id, establishmentNumber):
self.id = id
self.establishmentNumber = establishmentNumber
update_this = Example.query.filter_by(_id=school._id.iloc[0]).first()
update_this.establishmentNumber = 'bob'
db.session.commit()
examples = Example.query.all()
examples
for ex in examples:
print (ex.establishmentNumber)
This will update correctly, however, when I try to add a completely new school to the db, with this code:
new_ex = Example('5c12345scl', 'fifth')
db.session.add(new_ex)
db.session.commit()
I get this error:
IntegrityError: (MySQLdb._exceptions.IntegrityError) (1364, "Field '_id' doesn't have a default value")
[SQL: INSERT INTO schools (`establishmentNumber`) VALUES (%s)]
[parameters: ('fifth',)]
(Background on this error at: http://sqlalche.me/e/gkpj)
Does anyone know how to get rid of this error?
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' UPDATE '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The above is working now. I am now trying to combine the add and update functions so that it checks if the id exists in the table. If not, it inserts a new row. If it does, then it just updates the values. Below is my code so far, thanks to @James Summers:
class Example(db.Model):
__tablename__ = 'schools'
_id = db.Column('_id', db.Unicode, primary_key=True)
establishmentNumber = db.Column('establishmentNumber', db.Unicode)
laCode = db.Column('laCode', db.Unicode)
urn = db.Column('urn', db.Unicode)
name = db.Column('name', db.Unicode)
phaseOfEducation = db.Column('phaseOfEducation', db.Unicode)
wondeID = db.Column('wondeID', db.Unicode)
def __init__(self, _id, establishmentNumber, laCode, urn, name, phaseOfEducation, wondeID):
self._id = _id
self.establishmentNumber = establishmentNumber
self.laCode = laCode
self.urn = urn
self.name = name
self.phaseOfEducation = phaseOfEducation
self.wondeID = wondeID
def add_or_update(self, _id, establishmentNumber, laCode, urn, name, phaseOfEducation, wondeID):
update_this = Example.query.filter_by(_id=school._id.iloc[0]).first()
if not update_this:
new_ex = Example(school._id.iloc[0], school.establishmentNumber.iloc[0], school.laCode.iloc[0], school.urn.iloc[0], school.name.iloc[0], school.phaseOfEducation.iloc[0], school.wondeID.iloc[0])
db.session.add(new_ex)
db.session.commit()
else:
update_this.establishmentNumber = 'hello'
db.session.commit()
return new_ex
It is not producing any errors, but it's not adding or updating either. Can anyone see what I've done wrong?
The error is perhaps with your constructor.
You have a class member that is: _id = db.Column('_id', db.Unicode, primary_key=True)
but in your constructor you're setting self.id = id
A fix for this problem would be to either update your model for the code to look like this:
class Example(db.Model):
__tablename__ = 'schools'
_id = db.Column('_id', db.Unicode, primary_key=True)
establishmentNumber = db.Column('establishmentNumber', db.Unicode)
def __init__(self, id, establishmentNumber):
self._id = id
self.establishmentNumber = establishmentNumber
or what someone in the comments suggested to do by adding a default value to your column. However, I would not suggest adding a default value to your primary key.
Another possible solution for this problem is to create an add_or_update
method to your class, which is the better solution for the long run. You do it by adding a class method which gets a result by id, if it doesn't exist, your code will create one or update the existing retrieved result. This is how you would implement the following code:
class Example(db.Model):
__tablename__ = 'schools'
_id = db.Column('_id', db.Unicode, primary_key=True)
establishmentNumber = db.Column('establishmentNumber', db.Unicode)
def __init__(self, id, establishmentNumber):
self._id = id
self.establishmentNumber = establishmentNumber
@classmethod
def add_or_update(cls, example_id, establishmentNumber):
entity = cls.query.filter_by(id=example_id).first()
if not entity:
entity = cls(example_id, establishmentNumber)
entity.establishmentNumber = establishmentNumber
db.session.add(entity)
db.session.commit()
return entity
Good luck and cheers!