PyQt5 Qsqltablemodel типы данных «несовместимы в операторе равно» с данными более 128 символов

#python #sql #qt #pyqt5 #qsqltablemodel

Вопрос:

В настоящее время я работаю над программным обеспечением на базе PyQt5, которое подключается к базе данных SQL для управления заданиями для большого числа людей. URL-адреса для этих документов о назначении довольно длинные, до ~260 символов, и я столкнулся с ошибкой при попытке редактировать записи с помощью этих длинных ссылок.

QODBCResult::exec: Не удается выполнить инструкцию: «[Microsoft][Драйвер ODBC SQL Server][SQL Server]Типы данных nvarchar(max) и ntext несовместимы в операторе равно. [Microsoft][Драйвер ODBC SQL Server][Инструкции SQL Server]не удалось подготовить».

Ошибка возникает всякий раз, когда длина ссылки превышает 128 символов, поэтому я предполагаю, что где-то есть ограничение в 16 байт, но я не знаю, где. Я попытался изменить типы данных в базе данных SQL на nvarchars разного размера, nchars и другие. Я также проверил, чтобы убедиться, что он не делает что-то странное специально со ссылками, и использовал обычный текст. Я даже попытался изменить его на ntext, и ошибка будет означать, что

…Типы данных ntext и ntext несовместимы в операторе равно…

Вот код для моего окна управления курсом. Я относительно новичок в Qt, в основном просто изучаю его на основе случайных сообщений на форуме и того, что я могу понять из документации, поэтому, вероятно, у меня есть некоторые плохие практики в этом.

 import sys
import configparser
from PyQt5 import QtGui, QtCore, uic
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox, QTableView, QLabel, QItemDelegate
from PyQt5.QtSql import QSqlTableModel, QSqlDatabase
from PyQt5.QtCore import QVariant, Qt
from views.ui_coursesTable import Ui_Table

class ManageCoursesWindow(QWidget, Ui_Table):
    def __init__(self, db):
        super(ManageCoursesWindow, self).__init__()

        self.config = configparser.ConfigParser()
        self.config.read('config.ini')
        
        self.areEdits=False
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.ui = Ui_Table()
        self.ui.setupUi(self)
        
        self.db = db
        self.db.setDatabaseName(self.config.get('Database', 'conn_string'))
        self.db.open()
        self.model = QSqlTableModel()
        self.initializedModel()
        self.ui.tableView.setModel(self.model)
        self.ui.tableView.setColumnWidth(1,235)
        self.ui.tableView.setColumnWidth(2,100)
        self.ui.tableView.setColumnWidth(9,85)
        self.setWindowTitle("Manage Courses")

        self.ui.addRow.clicked.connect(self.onAddRow)
        self.ui.deleteRow.clicked.connect(self.onDeleteRow)
        self.ui.submitAll.clicked.connect(self.onSave)
        self.ui.filterButton.clicked.connect(self.onFilter)

    def initializedModel(self):
        self.model.setTable("tbl_courses")
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.select()

    def onAddRow(self):
        self.model.insertRows(self.model.rowCount(), 1)
        self.areEdits=True

    def onDeleteRow(self):
        self.model.removeRow(self.ui.tableView.currentIndex().row())
        self.areEdits=True

    def onSave(self):
        self.areEdits=False
        self.model.submitAll()

    def maybeSave (self):
        if self.areEdits:
            if QMessageBox.question(self, 'Save?', "Quit without saving?", QMessageBox.Yes | QMessageBox.No)==QMessageBox.Yes:
                return True
            else:
                return False
        else:
            return True

    def closeEvent(self, event):
        if maybeSave:
            self.db.close()
            event.accept()

    def onFilter(self):
        course = self.ui.filterField.text().strip()
        self.model.setFilter('')
        self.model.setFilter("Course_Number LIKE '%" course "%' OR Course_Title LIKE '%" course "%'")
    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle("Fusion")

    window = ManageCoursesWindow(QSqlDatabase.addDatabase("QODBC"))
    window.show()
    sys.exit(app.exec_())
 

Это программное обеспечение раньше запускалось из базы данных SQLITE, но другой человек, который временно помогал с этим программным обеспечением, несколько месяцев назад изменил его, чтобы использовать полную базу данных SQL. Я не помню, чтобы эта ошибка существовала тогда, хотя вполне возможно, что в тот момент мы просто не использовали ссылки >128 символов

Комментарии:

1. Может быть, это связано с этим отчетом ?

2. @musicamante спасибо за эту ссылку. Это не возникало ни разу за все время, пока я гуглил, но, похоже, это очень похоже на мою проблему. Было бы действительно досадно, если бы просто не было возможности иметь больше символов из-за проблемы с ODBC.