예제 #1
0
def report_month_sales(file, dbase):
    for_date = date = datetime.date.today()
    query = QSqlQuery("SELECT employee.firstname AS firstname, employee.lastname AS lastname, employee.middlename AS middlename, \
            count(orders.id) AS qnt, sum(orders.price) AS price \
        FROM employee INNER JOIN orders ON employee.id = orders.employee_id \
        WHERE orders.regdate >= \"{}\"\
        GROUP BY employee.firstname, employee.lastname, employee.middlename".format(for_date.strftime("%Y.%m.01")), dbase)
    if not query.isActive():
        return print(query.lastError().text())
    with open("reports/emp_sales.html", "r") as f:
        html = f.read()
    rows = []
    qnt_total = 0
    price_total = 0
    while query.next():
        rows.append("<tr><td align='center'>{}</td><td align='center'>{}</td><td align='center'>{}</td></tr>".format(
            "{} {}. {}.".format(query.value("lastname"), query.value("firstname")[0], query.value("middlename")[0]),
            int(query.value("qnt")), int(query.value("price"))))
        qnt_total += int(query.value("qnt"))
        price_total += int(query.value("price"))
    rows.append("<b><tr><td align='right'>{}</td><td align='center'>{}</td><td align='center'>{}</td></tr></b>".format(
        "Итого:", qnt_total, price_total))
    date = datetime.date.today().strftime("%d.%m.%Y")
    html = html.format(for_month = for_date.strftime("%m.%Y"), date = date, rows = "\n".join(rows))
    tmpfile = "/tmp/report{}.html".format(random.randrange(1000000))
    with open(tmpfile, "w") as f:
        f.write(html)
    subprocess.call(["wkhtmltopdf", tmpfile, file])
예제 #2
0
def report_day_sales(for_date, file, dbase):
    query = QSqlQuery("SELECT shop.name AS name, sum(order_detail.quantity) AS qnt, sum(detail.price * order_detail.quantity) AS price \
        FROM shop INNER JOIN orders ON shop.id = orders.shop_id \
        INNER JOIN order_detail ON order_detail.order_id = orders.id \
        INNER JOIN detail ON detail.id = order_detail.detail_id \
        WHERE orders.regdate = \"{}\"\
        GROUP BY shop.name".format(for_date.toString("yyyy.MM.dd")), dbase)
    if not query.isActive():
        return print(query.lastError().text())
    with open("reports/goods.html", "r") as f:
        html = f.read()
    rows = []
    qnt_total = 0
    price_total = 0
    while query.next():
        rows.append("<tr><td align='center'>{}</td><td align='center'>{}</td><td align='center'>{}</td></tr>".format(
            query.value("name"), int(query.value("qnt")), int(query.value("price"))))
        qnt_total += int(query.value("qnt"))
        price_total += int(query.value("price"))
    rows.append("<b><tr><td align='right'>{}</td><td align='center'>{}</td><td align='center'>{}</td></tr></b>".format(
        "Итого:", qnt_total, price_total))
    date = datetime.date.today().strftime("%d.%m.%Y")
    html = html.format(for_day = for_date.toString("dd.MM.yyyy"), date = date, rows = "\n".join(rows))
    tmpfile = "/tmp/report{}.html".format(random.randrange(1000000))
    with open(tmpfile, "w") as f:
        f.write(html)
    subprocess.call(["wkhtmltopdf", tmpfile, file])
예제 #3
0
 def addButtonClicked(self):
     shop = self.shopModel.record(self.list.currentIndex().row())
     query = QSqlQuery("SELECT detail.id as id, CONCAT(detail.article, \": \", detail.name) as name \
         FROM detail WHERE NOT(detail.id IN (SELECT detail_id FROM shop_detail \
             WHERE shop_id={}))".format(shop.value("id")))
     details = {}
     while query.next():
         details[query.value("name")] = query.value("id")
     if not details:
         return QMessageBox.warning(None, "Ошибка добавления",
             "Не удалось добавить новый товар на склад: все возможные товары уже добавлены.")
     choice, ok = QInputDialog.getItem(None, "Товар", "Укажите товар:",
         list(details.keys()), 0, False)
     if not ok: return
     qnt, ok = QInputDialog.getInt(None, "Количество", "Укажите количество товара:",
         1, 1)
     if not ok: return
     detail_id = details[choice]
     shop_id = shop.value("id")
     query = QSqlQuery("INSERT INTO shop_detail (shop_id, detail_id, quantity) \
         VALUES ({}, {}, {})".format(shop_id, detail_id, qnt))
     if not query.isActive():
         print(query.lastError().text())
     self.setShopIndex(self.list.currentIndex().row())
     self.table.selectionModel().clearSelection()
예제 #4
0
    def _start_query(self):
        self.setCursor(Qt.WaitCursor)
        QCoreApplication.processEvents()
        # noinspection PyBroadException
        try:
            self.model.clear()
            QCoreApplication.processEvents()

            line = self.text.text().strip()
            if not line:
                self.model.setQuery("SELECT media_id from Media;")
                # self.model.setQuery("SELECT DISTINCT media_id from ManifoldItems NATURAL JOIN Manifolds WHERE ready;")
                return

            if line == '@import':
                _source_dir = QFileDialog.getExistingDirectory(
                    self, "Select a directory to import", "",
                    QFileDialog.DontResolveSymlinks | QFileDialog.ReadOnly)
                _source_dir = os.path.abspath(_source_dir)
                assert os.path.isdir(_source_dir)
                self._logger.info(f"Starting ingestion of {_source_dir}")
                self._py_db.ingest_file_directory(
                    _source_dir
                )  # NOTE: this will freeze the GUI for a long time!
                self._py_db.notify_bg_manifold_build()
                self._py_db.thumbs_load()
                self._logger.info(f"Ingestion finished. ")
                _source_dir_url_like = 'file:' + pathname2url(
                    _source_dir) + '%'
                query = QSqlQuery()
                query.prepare(
                    'SELECT media_id FROM MediaLocations WHERE url LIKE ? ORDER BY url'
                )
                query.bindValue(0, _source_dir_url_like)
                self.model.setQuery(query)
                return

            results_id, inserted = self._py_db.search(line,
                                                      n=1000,
                                                      search_k=-1)

            query_s = (f'SELECT media_id FROM results.ResultsMediaFiltered '
                       f'WHERE results_id = {results_id:d} ORDER BY rank ASC')

            query = QSqlQuery()
            query.exec(query_s)
            if not query.isActive():
                self._logger.debug(f'results query: {query.lastQuery():s}')
                self._logger.error(
                    f'results query error: {query.lastError().text():s}')
            self.model.setQuery(query)
        except Exception:
            import traceback
            traceback.print_exc()
        finally:
            self.setCursor(Qt.ArrowCursor)
예제 #5
0
 def deleteButtonClicked(self):
     if not self.table.currentIndex().isValid(): return
     detail = self.detailModel.record(self.table.currentIndex().row())
     shop = self.shopModel.record(self.list.currentIndex().row())
     query = QSqlQuery("DELETE FROM shop_detail WHERE \
         shop_id={} AND detail_id={} LIMIT 1".format(
             shop.value("id"), detail.value("id")))
     if not query.isActive():
         print(query.lastError().text())
     self.setShopIndex(self.list.currentIndex().row())
예제 #6
0
 def deleteButtonClicked(self):
     if not self.orderTable.currentIndex().isValid(): return
     detail = self.detailModel.record(self.orderTable.currentIndex().row())
     order = self.form.currentRecord()
     query = QSqlQuery("DELETE FROM order_detail WHERE \
         order_id={} AND detail_id={} LIMIT 1".format(
             order.value("id"), detail.value("id")))
     query.exec_()
     if not query.isActive():
         print(query.lastError().text())
     self.form.update()
예제 #7
0
 def editButtonClicked(self):
     detail = self.detailModel.record(self.table.currentIndex().row())
     qnt, ok = QInputDialog.getInt(None, "Количество", "Укажите количество товара:",
         detail.value("qnt"), 0)
     if not ok: return
     shop = self.shopModel.record(self.list.currentIndex().row())
     if qnt > 0:
         query = QSqlQuery("UPDATE shop_detail SET quantity={} \
             WHERE shop_id={} AND detail_id={}".format(qnt,
                 shop.value("id"), detail.value("id")))
     else:
         query = QSqlQuery("DELETE FROM shop_detail WHERE \
             shop_id={} AND detail_id={} LIMIT 1".format(
                 shop.value("id"), detail.value("id")))
     if not query.isActive():
         print(query.lastError().text())
     self.setShopIndex(self.list.currentIndex().row())
예제 #8
0
 def editButtonClicked(self):
     detail = self.detailModel.record(self.orderTable.currentIndex().row())
     qnt, ok = QInputDialog.getInt(None, "Количество", "Укажите количество товара:",
         detail.value("qnt"), 0)
     if not ok: return
     order = self.form.currentRecord()
     if qnt > 0:
         query = QSqlQuery("UPDATE order_detail SET quantity={} \
             WHERE order_id={} AND detail_id={}".format(qnt,
                 order.value("id"), detail.value("id")))
     else:
         query = QSqlQuery("DELETE FROM order_detail WHERE \
             order_id={} AND detail_id={} LIMIT 1".format(
                 order.value("id"), detail.value("id")))
     query.exec_()
     if not query.isActive():
         print(query.lastError().text())
     self.form.update()
예제 #9
0
 def addButtonClicked(self):
     order = self.form.currentRecord()
     query = QSqlQuery("SELECT detail.id as id, CONCAT(detail.article, \": \", detail.name) as name \
         FROM detail WHERE NOT(detail.id IN (SELECT detail_id FROM order_detail \
             WHERE order_id={}))".format(order.value("id")))
     details = {}
     while query.next():
         details[query.value("name")] = query.value("id")
     if not details:
         return QMessageBox.warning(None, "Ошибка добавления",
             "Не удалось добавить новый товар к заказу: все возможные товары уже добавлены.")
     choice, ok = QInputDialog.getItem(None, "Товар", "Укажите товар:",
         list(details.keys()), 0, False)
     if not ok: return
     qnt, ok = QInputDialog.getInt(None, "Количество", "Укажите количество товара:", 1, 1)
     if not ok: return
     detail_id = details[choice]
     order_id = order.value("id")
     query = QSqlQuery("INSERT INTO order_detail (order_id, detail_id, quantity) \
         VALUES ({}, {}, {})".format(order_id, detail_id, qnt))
     if not query.isActive():
         print(query.lastError().text())
     self.form.update()
예제 #10
0
class Query:
    """A prepared SQL query."""
    def __init__(self, querystr, forward_only=True):
        """Prepare a new SQL query.

        Args:
            querystr: String to prepare query from.
            forward_only: Optimization for queries that will only step forward.
                          Must be false for completion queries.
        """
        self.query = QSqlQuery(QSqlDatabase.database())

        log.sql.debug('Preparing SQL query: "{}"'.format(querystr))
        ok = self.query.prepare(querystr)
        self._check_ok('prepare', ok)
        self.query.setForwardOnly(forward_only)

    def __iter__(self):
        if not self.query.isActive():
            raise BugError("Cannot iterate inactive query")
        rec = self.query.record()
        fields = [rec.fieldName(i) for i in range(rec.count())]
        rowtype = collections.namedtuple(  # type: ignore[misc]
            'ResultRow', fields)

        while self.query.next():
            rec = self.query.record()
            yield rowtype(*[rec.value(i) for i in range(rec.count())])

    def _check_ok(self, step, ok):
        if not ok:
            query = self.query.lastQuery()
            error = self.query.lastError()
            msg = 'Failed to {} query "{}": "{}"'.format(
                step, query, error.text())
            raise_sqlite_error(msg, error)

    def _bind_values(self, values):
        for key, val in values.items():
            self.query.bindValue(':{}'.format(key), val)
        if any(val is None for val in self.bound_values().values()):
            raise BugError("Missing bound values!")

    def run(self, **values):
        """Execute the prepared query."""
        log.sql.debug('Running SQL query: "{}"'.format(self.query.lastQuery()))

        self._bind_values(values)
        log.sql.debug('query bindings: {}'.format(self.bound_values()))

        ok = self.query.exec_()
        self._check_ok('exec', ok)

        return self

    def run_batch(self, values):
        """Execute the query in batch mode."""
        log.sql.debug('Running SQL query (batch): "{}"'.format(
            self.query.lastQuery()))

        self._bind_values(values)

        db = QSqlDatabase.database()
        ok = db.transaction()
        self._check_ok('transaction', ok)

        ok = self.query.execBatch()
        try:
            self._check_ok('execBatch', ok)
        except Error:
            # Not checking the return value here, as we're failing anyways...
            db.rollback()
            raise

        ok = db.commit()
        self._check_ok('commit', ok)

    def value(self):
        """Return the result of a single-value query (e.g. an EXISTS)."""
        if not self.query.next():
            raise BugError("No result for single-result query")
        return self.query.record().value(0)

    def rows_affected(self):
        return self.query.numRowsAffected()

    def bound_values(self):
        return self.query.boundValues()
예제 #11
0
conn.setHostName("127.0.0.1")
conn.setUserName("postgres")
conn.setPassword("12345")
conn.setPort("5432")
"""

# Открываем базу данных
conn = QSqlDatabase.addDatabase('QSQLITE')

# Определяем путь до базы данных
conn.setDatabaseName('test.sqlite3')

if conn.open():
    # Выполняем действия с базой
    query = QSqlQuery()
    query.exec("select * from vendors")
    results = []
    if query.isActive():
        query.first()
        while query.isValid():
            results.append(query.value('name'))
            query.next()
        for el in results:
            print(el)
else:
    # Выводим текст ошибки
    print(conn.lastError().text())

conn.close()

bin()
예제 #12
0
class Query:

    """A prepared SQL query."""

    def __init__(self, querystr, forward_only=True):
        """Prepare a new SQL query.

        Args:
            querystr: String to prepare query from.
            forward_only: Optimization for queries that will only step forward.
                          Must be false for completion queries.
        """
        self.query = QSqlQuery(QSqlDatabase.database())

        log.sql.debug('Preparing SQL query: "{}"'.format(querystr))
        ok = self.query.prepare(querystr)
        self._check_ok('prepare', ok)
        self.query.setForwardOnly(forward_only)

    def __iter__(self):
        if not self.query.isActive():
            raise BugError("Cannot iterate inactive query")
        rec = self.query.record()
        fields = [rec.fieldName(i) for i in range(rec.count())]
        rowtype = collections.namedtuple('ResultRow', fields)

        while self.query.next():
            rec = self.query.record()
            yield rowtype(*[rec.value(i) for i in range(rec.count())])

    def _check_ok(self, step, ok):
        if not ok:
            query = self.query.lastQuery()
            error = self.query.lastError()
            msg = 'Failed to {} query "{}": "{}"'.format(step, query,
                                                         error.text())
            raise_sqlite_error(msg, error)

    def _bind_values(self, values):
        for key, val in values.items():
            self.query.bindValue(':{}'.format(key), val)
        if any(val is None for val in self.bound_values().values()):
            raise BugError("Missing bound values!")

    def run(self, **values):
        """Execute the prepared query."""
        log.sql.debug('Running SQL query: "{}"'.format(
            self.query.lastQuery()))

        self._bind_values(values)
        log.sql.debug('query bindings: {}'.format(self.bound_values()))

        ok = self.query.exec_()
        self._check_ok('exec', ok)

        return self

    def run_batch(self, values):
        """Execute the query in batch mode."""
        log.sql.debug('Running SQL query (batch): "{}"'.format(
            self.query.lastQuery()))

        self._bind_values(values)

        db = QSqlDatabase.database()
        ok = db.transaction()
        self._check_ok('transaction', ok)

        ok = self.query.execBatch()
        try:
            self._check_ok('execBatch', ok)
        except Error:
            # Not checking the return value here, as we're failing anyways...
            db.rollback()
            raise

        ok = db.commit()
        self._check_ok('commit', ok)

    def value(self):
        """Return the result of a single-value query (e.g. an EXISTS)."""
        if not self.query.next():
            raise BugError("No result for single-result query")
        return self.query.record().value(0)

    def rows_affected(self):
        return self.query.numRowsAffected()

    def bound_values(self):
        return self.query.boundValues()
예제 #13
0
class Query:
    """A prepared SQL query."""
    def __init__(self,
                 database: Database,
                 querystr: str,
                 forward_only: bool = True) -> None:
        """Prepare a new SQL query.

        Args:
            database: The Database object on which to operate.
            querystr: String to prepare query from.
            forward_only: Optimization for queries that will only step forward.
                          Must be false for completion queries.
        """
        self._database = database
        self.query = QSqlQuery(database.qt_database())

        log.sql.vdebug(f'Preparing: {querystr}')  # type: ignore[attr-defined]
        ok = self.query.prepare(querystr)
        self._check_ok('prepare', ok)
        self.query.setForwardOnly(forward_only)

    def __iter__(self) -> Iterator[Any]:
        if not self.query.isActive():
            raise BugError("Cannot iterate inactive query")
        rec = self.query.record()
        fields = [rec.fieldName(i) for i in range(rec.count())]
        rowtype = collections.namedtuple(  # type: ignore[misc]
            'ResultRow', fields)

        while self.query.next():
            rec = self.query.record()
            yield rowtype(*[rec.value(i) for i in range(rec.count())])

    def _check_ok(self, step: str, ok: bool) -> None:
        if not ok:
            query = self.query.lastQuery()
            error = self.query.lastError()
            msg = f'Failed to {step} query "{query}": "{error.text()}"'
            raise_sqlite_error(msg, error)

    def _bind_values(self, values: Mapping[str, Any]) -> Dict[str, Any]:
        for key, val in values.items():
            self.query.bindValue(f':{key}', val)

        bound_values = self.bound_values()
        if None in bound_values.values():
            raise BugError("Missing bound values!")

        return bound_values

    def run(self, **values: Any) -> 'Query':
        """Execute the prepared query."""
        log.sql.debug(self.query.lastQuery())

        bound_values = self._bind_values(values)
        if bound_values:
            log.sql.debug(f'    {bound_values}')

        ok = self.query.exec()
        self._check_ok('exec', ok)

        return self

    def run_batch(self, values: Mapping[str, MutableSequence[Any]]) -> None:
        """Execute the query in batch mode."""
        log.sql.debug(f'Running SQL query (batch): "{self.query.lastQuery()}"')

        self._bind_values(values)

        db = self._database.qt_database()
        ok = db.transaction()
        self._check_ok('transaction', ok)

        ok = self.query.execBatch()
        try:
            self._check_ok('execBatch', ok)
        except Error:
            # Not checking the return value here, as we're failing anyways...
            db.rollback()
            raise

        ok = db.commit()
        self._check_ok('commit', ok)

    def value(self) -> Any:
        """Return the result of a single-value query (e.g. an EXISTS)."""
        if not self.query.next():
            raise BugError("No result for single-result query")
        return self.query.record().value(0)

    def rows_affected(self) -> int:
        """Return how many rows were affected by a non-SELECT query."""
        assert not self.query.isSelect(), self
        assert self.query.isActive(), self
        rows = self.query.numRowsAffected()
        assert rows != -1
        return rows

    def bound_values(self) -> Dict[str, Any]:
        return self.query.boundValues()
예제 #14
0
    def dropEvent(self, a0: QDropEvent) -> None:
        data = a0.mimeData()
        action = a0.dropAction()
        if action == Qt.IgnoreAction:
            a0.ignore()
            return
        if not data.hasFormat('text/uri-list'):
            a0.ignore()
            return
        a0.accept()
        self.setCursor(Qt.WaitCursor)
        self.model.clear()
        QCoreApplication.processEvents()

        ul = data.data('text/uri-list').data().decode().splitlines()
        ul = map(str.strip, ul)
        ul = filter(lambda _uri: not _uri.startswith('#'), ul)
        ul = [
            'file:/' +
            _uri[len('file:///'):] if _uri.startswith('file:///') else _uri
            for _uri in ul
        ]
        ul = list(ul)

        file_binds = []
        dir_binds = []

        # Ingest file and dirs from received uri-list
        for uri in ul:
            if uri.startswith('file:'):
                pathname = url2pathname(uri[len('file:'):])
                if os.path.isdir(pathname):
                    self._logger.info(f'RECURSIVELY ADDING {pathname}')
                    out = self._py_db.ingest_file_directory(pathname)
                    dir_binds.append(f'{uri}%')
                    self._logger.debug(
                        f'ingest_file_directory({pathname}) -> {out}')
                    continue

            self._logger.info(f'ADDING {uri}')
            media_id, flags, ex = self._py_db.try_ingest_url(uri)
            if ex is not None:
                self._logger.exception(f'FAILING {uri}: {ex}')
            else:
                file_binds.append(uri)
                self._logger.debug(f'{media_id=} {flags=} {ex=}')

        self._py_db.notify_bg_manifold_build()
        self._py_db.thumbs_load()

        # Build WHERE expression with file and dir binds
        conditions = []
        file_placeholders = ', '.join('?' * len(file_binds))
        if file_placeholders:
            file_placeholders = f'url IN ({file_placeholders})'
            conditions.append(file_placeholders)
        conditions.extend(['url LIKE ?'] * len(dir_binds))

        # Prepare query and bind values for file and dirs
        query = QSqlQuery()
        query.prepare(
            f'SELECT media_id FROM MediaLocations WHERE {" OR ".join(conditions)} ORDER BY url'
        )
        i = -1
        for i, bind in enumerate(file_binds):
            query.bindValue(i, bind)
        for j, bind in zip(range(i + 1, i + 1 + len(dir_binds)), dir_binds):
            query.bindValue(j, bind)
        query.exec()

        if not query.isActive():
            self._logger.debug(f'results query: {query.lastQuery():s}')
            self._logger.error(
                f'results query error: {query.lastError().text():s}')

        self.model.setQuery(query)
        self.setCursor(Qt.ArrowCursor)