Как отобразить 2 таблицы SQLite с отношением один ко многим в один QTableWidget

У меня есть следующие две таблицы в Db с отношением один ко многим:

self.c.execute("CREATE TABLE IF NOT EXISTS dispatch("
                       "id_dispatch INTEGER PRIMARY KEY AUTOINCREMENT,"
                       "d_date TEXT,"
                       "d_mill TEXT,"
                       "d_buyer TEXT,"
                       "d_addFreight INTEGER,"
                       "d_subFreight INTEGER,"
                       "d_amount INTEGER,"
                       "d_cd INTEGER,"
                       "d_comm INTEGER,"
                       "d_netAmount INTEGER)")
        self.c.execute("CREATE TABLE IF NOT EXISTS dispatch_products("
                       "dispatch_id INTEGER NOT NULL REFERENCES DISPATCH(id_dispatch),"
                       "product INTEGER,"
                       "quantity INTEGER,"
                       "rate INTEGER)")

Я пытаюсь объединить эти две таблицы в одну и отобразить в одной таблице, используя следующий код:

def loadTable(self):
    connection = sqlite3.connect('main_databaseSample.db')
    query = "CREATE VIEW myview as SELECT d_buyer," \
            "d_date, product, quantity, rate, d_amount, d_addFreight, d_subFreight, d_netAmount from " \
            "dispatch, dispatch_products WHERE dispatch.id_dispatch = dispatch_products.dispatch_id"
    query = "SELECT * FROM myview"
    result = connection.execute(query)
    self.tableWidget.setRowCount(0)
    for row_number, row_data in enumerate(result):
        self.tableWidget.insertRow(row_number)
        for column_number, data in enumerate(row_data):
            self.tableWidget.setItem(row_number, column_number,QtWidgets.QTableWidgetItem(str(data)))
    connection.close()

ПРОБЛЕМА: заказы с несколькими товарами повторяются. Как удалить несколько записей, имеющих отношение "один ко многим"?

Образец данных:

dispatch table:
ID date   mill buyer addF subF amount cd comm netAmount
1  15-10  abc  A     0    0    100    0  0    100
2  16-10  xyz  B     0    0    200    0  0    200

dispatch_products table:
Dispatch_ID product qty rate
1           M       40  1
1           A       60  1
2           S       50  4

Code Output:
buyer date  product quantity rate amount addFreight subFreight NetAmount
A     15-10 M       40       1    100    0          0          100
A     15-10 A       60       1    100    0          0          100
B     16-10 S       50       4    200    0          0          200

Expected Output:
buyer date  product quantity rate amount addFreight subFreight NetAmount
A     15-10 M       40       1    100    0          0          100
            A       60       1                           
B     16-10 S       50       4    200    0          0          200
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
411
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Задача состоит в том, чтобы обнаружить, что для него есть равные элементы, мы должны добавить еще один элемент в представление, dispatch_id или id_dispatch и отсортировать их. После обнаружения изменения dispatch_id присоедините необходимые строки с помощью setSpan(), как показано ниже:

from PyQt5 import QtCore, QtWidgets
import sqlite3

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        button = QtWidgets.QPushButton("Press me")
        button.clicked.connect(self.load_table)
        self.tableWidget = QtWidgets.QTableWidget()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(button)
        lay.addWidget(self.tableWidget)

    @QtCore.pyqtSlot()
    def load_table(self):
        self.tableWidget.setRowCount(0)
        self.tableWidget.setColumnCount(9)

        connection = sqlite3.connect('main_databaseSample.db')

        connection.execute("DROP VIEW IF EXISTS myview;")
        query = "CREATE VIEW myview as SELECT dispatch_id, d_buyer," \
            "d_date, product, quantity, rate, d_amount, d_addFreight, d_subFreight, d_netAmount from " \
            "dispatch, dispatch_products WHERE dispatch.id_dispatch = dispatch_products.dispatch_id " \
            "ORDER BY dispatch_id ASC;"
        connection.execute(query)
        query = "SELECT * FROM myview"
        result = connection.execute(query)
        last_id = -1
        start_row = 0
        for row, row_data in enumerate(result):
            self.tableWidget.insertRow(row)
            current_id, *other_values = row_data 
            for col, data in enumerate(other_values):
                it = QtWidgets.QTableWidgetItem(str(data))
                self.tableWidget.setItem(row, col, it)
            if last_id != current_id and last_id != -1:
                self.apply_span(start_row, row - start_row)
                start_row = row
            last_id = current_id
        if start_row != row:
            self.apply_span(start_row, self.tableWidget.rowCount() - start_row)

    def apply_span(self, row, nrow):
        if nrow <= 1:
            return
        for c in (0, 1, 5, 6, 7, 8):
            self.tableWidget.setSpan(row, c, nrow, 1)
            for r in range(row+1, row+nrow):
                t = self.tableWidget.takeItem(r, c)
                del t

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

Добавляя больше данных, мы можем увидеть следующий результат

ваше решение работает, но я получаю следующее предупреждение, когда загружаю таблицу QTableView :: setSpan: single cell span не будет добавлен. Отображался 12 раз.

user3170565 29.10.2018 09:09

@ user3170565 Исправил, предупреждения не заметил. попробуйте вернуть пожалуйста.

eyllanesc 29.10.2018 10:41

Спасибо! теперь это работает. Но когда я пытаюсь распечатать эти данные таблицы, диапазон не применяется. Я что-то упускаю?

user3170565 29.10.2018 11:43

@ user3170565 С каким кодом печатается таблица ?. С другой стороны, об этом требовании не может быть и речи о том, что я бы пригласил для создания нового вопроса, и, наконец, если мой ответ поможет вам, не забудьте отметить его как правильный, если вы не знаете, как это сделать, просмотрите the тур, это лучший способ поблагодарить.

eyllanesc 29.10.2018 11:48

Я пытался с этим кодом печати def handlePaintRequest(self, printer): document = QtGui.QTextDocument() cursor = QtGui.QTextCursor(document) table = cursor.insertTable( self.tableWidget.rowCount(), self.tableWidget.columnCount()) for row in range(table.rows()): for col in range(table.columns()): cursor.insertText(self.tableWidget.item(row, col).text()) cursor.movePosition(QtGui.QTextCursor.NextCell) document.print_(printer)

user3170565 29.10.2018 11:50

@ user3170565, пожалуйста, как я уже сказал, задайте новый вопрос, и он будет лучше смотреть и понимать ваш код. :-)

eyllanesc 29.10.2018 11:51

Конечно, я отправлю новый вопрос по этому поводу. Спасибо!

user3170565 29.10.2018 11:52

Другие вопросы по теме