Ошибка целостности при попытке загрузки в MySQL БД в python - PullRequest
1 голос
/ 20 февраля 2020

У меня есть этот код, который позволяет мне обновлять данные школы в базе данных mySQL, если идентификатор уже существует. Тем не менее, чего я также пытаюсь добиться, так это того, что если идентификатор не существует в БД, он вставляет эти значения. Вот код, который я получил до сих пор:

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)

Однако он будет корректно обновляться, когда я попытаюсь добавить в базу данных совершенно новую школу с этим кодом:

new_ex = Example('5c12345scl', 'fifth')
db.session.add(new_ex)
db.session.commit()

Я получаю эту ошибку:

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)

Кто-нибудь знает, как избавиться от этой ошибки?

'' '' '' '' '' '' '' '' ''''''''''''''''''''''''''''''''''''''''''' ОБНОВИТЬ '''''' «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» «» '' '

Выше работает сейчас. Сейчас я пытаюсь объединить функции добавления и обновления, чтобы он проверял, существует ли идентификатор в таблице. Если нет, он вставляет новую строку. Если это так, то он просто обновляет значения. Ниже приведен мой код, благодаря @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

Он не выдает никаких ошибок, но не добавляет и не обновляет. Кто-нибудь может увидеть, что я сделал не так?

Ответы [ 2 ]

1 голос
/ 20 февраля 2020

Благодаря комментариям @ Акины. Я понял, что проблема была в коде этой функции:

def __init__(self, id, establishmentNumber):
    self.id = id
    self.establishmentNumber = establishmentNumber

Я написал идентификатор без подчеркивания, так что это фиксированная версия:

def __init__(self, _id, establishmentNumber):
    self._id = _id
    self.establishmentNumber = establishmentNumber
0 голосов
/ 20 февраля 2020

Возможно, ошибка в вашем конструкторе.

У вас есть член класса: _id = db.Column('_id', db.Unicode, primary_key=True)

, но в вашем конструкторе вы устанавливаете self.id = id

Исправление для этой проблемы - обновление ваша модель для кода должна выглядеть так:

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

или что кто-то в комментариях предложил сделать, добавив значение по умолчанию в ваш столбец. Однако я бы не советовал добавлять значение по умолчанию к первичному ключу.

Другим возможным решением этой проблемы является создание метода add_or_update для вашего класса, который является лучшим решением в долгосрочной перспективе. Вы делаете это, добавляя метод класса, который получает результат по идентификатору. Если он не существует, ваш код создаст его или обновит существующий полученный результат. Вот как бы вы реализовали следующий код:

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

Удачи и ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...