wamdam/backy2

TypeError: SQLite DateTime type only accepts Python datetime and date objects as input.

noeyhuy opened this issue · 1 comments

i using sqlite. how to fix?.. same as reinstall : (
#48

[root@localhost ~]# backy2 backup file:///home/guest.img full_monday
INFO: $ /usr/local/bin/backy2 backup file:///home/guest.img full_monday
ERROR: Unexpected exception
ERROR: (builtins.TypeError) SQLite DateTime type only accepts Python datetime and date objects as input.
[SQL: INSERT INTO versions (uid, date, expire, name, snapshot_name, size, size_bytes, valid, protected) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)]
[parameters: [{'uid': 'b5037ffe-4cae-11ea-8221-90b11c43e4ce', 'size_bytes': 23006609408, 'date': '2020-02-11 09:13:03', 'valid': 0, 'protected': 0, 'size': 5486, 'snapshot_name': '', 'name': 'full_monday', 'expire': None}]]
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1173, in _execute_context
context = constructor(dialect, self, conn, *args)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/default.py", line 808, in _init_compiled
param.append(processorskey)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/dialects/sqlite/base.py", line 759, in process
"SQLite DateTime type only accepts Python "
TypeError: SQLite DateTime type only accepts Python datetime and date objects as input.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/backy2-2.10.7-py3.6.egg/backy2/scripts/backy.py", line 742, in main
func(**func_args)
File "/usr/local/lib/python3.6/site-packages/backy2-2.10.7-py3.6.egg/backy2/scripts/backy.py", line 95, in backup
version_uid = backy.backup(name, snapshot_name, source, hints, from_version, tags, expire_date)
File "/usr/local/lib/python3.6/site-packages/backy2-2.10.7-py3.6.egg/backy2/backy.py", line 521, in backup
version_uid = self._prepare_version(name, snapshot_name, source_size, from_version)
File "/usr/local/lib/python3.6/site-packages/backy2-2.10.7-py3.6.egg/backy2/backy.py", line 79, in _prepare_version
version_uid = self.meta_backend.set_version(name, snapshot_name, size, size_bytes, 0)
File "/usr/local/lib/python3.6/site-packages/backy2-2.10.7-py3.6.egg/backy2/meta_backends/sql.py", line 204, in set_version
self.session.commit()
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 1036, in commit
self.transaction.commit()
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 503, in commit
self._prepare_impl()
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 482, in _prepare_impl
self.session.flush()
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 2479, in flush
self._flush(objects)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 2617, in _flush
transaction.rollback(_capture_exception=True)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/util/langhelpers.py", line 68, in exit
compat.reraise(exc_type, exc_value, exc_tb)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/util/compat.py", line 153, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/session.py", line 2577, in _flush
flush_context.execute()
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py", line 422, in execute
rec.execute(self)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/unitofwork.py", line 589, in execute
uow,
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/persistence.py", line 245, in save_obj
insert,
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/orm/persistence.py", line 1084, in _emit_insert_statements
c = cached_connections[connection].execute(statement, multiparams)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 982, in execute
return meth(self, multiparams, params)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/sql/elements.py", line 293, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1101, in _execute_clauseelement
distilled_params,
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1176, in _execute_context
e, util.text_type(statement), parameters, None, None
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1476, in _handle_dbapi_exception
util.raise_from_cause(sqlalchemy_exception, exc_info)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/util/compat.py", line 398, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/util/compat.py", line 152, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1173, in _execute_context
context = constructor(dialect, self, conn, *args)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/engine/default.py", line 808, in _init_compiled
param.append(processorskey)
File "/usr/local/lib/python3.6/site-packages/SQLAlchemy-1.3.13-py3.6-linux-x86_64.egg/sqlalchemy/dialects/sqlite/base.py", line 759, in process
"SQLite DateTime type only accepts Python "
sqlalchemy.exc.StatementError: (builtins.TypeError) SQLite DateTime type only accepts Python datetime and date objects as input.
[SQL: INSERT INTO versions (uid, date, expire, name, snapshot_name, size, size_bytes, valid, protected) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)]
[parameters: [{'uid': 'b5037ffe-4cae-11ea-8221-90b11c43e4ce', 'size_bytes': 23006609408, 'date': '2020-02-11 09:13:03', 'valid': 0, 'protected': 0, 'size': 5486, 'snapshot_name': '', 'name': 'full_monday', 'expire': None}]]
INFO: Backy failed.

2.9.18 -> 2.10.5 type error after version upgrade.

# version : 2.9.18
[root@localhost ~]# vim /usr/local/lib/python3.6/site-packages/backy2-2.9.18-py3.6.egg/backy2/scripts/backy.py

from backy2.config import Config as _Config
from backy2.logging import logger, init_logging
from backy2.utils import hints_from_rbd_diff, backy_from_config
from functools import partial
from io import StringIO
from prettytable import PrettyTable
import argparse
import fileinput
import hashlib
import logging
import sys

import pkg_resources
version = pkg_resources.get_distribution('backy2').version

class Commands():
"""Proxy between CLI calls and actual backup code."""

def __init__(self, machine_output, Config):
    self.machine_output = machine_output
    self.Config = Config
    self.backy = backy_from_config(Config)


def backup(self, name, snapshot_name, source, rbd, from_version, tag=None):
    backy = self.backy()
    hints = None
    if rbd:
        data = ''.join([line for line in fileinput.input(rbd).readline()])
        hints = hints_from_rbd_diff(data)
    backy.backup(name, snapshot_name, source, hints, from_version, tag)
    backy.close()


def restore(self, version_uid, target, sparse, force):
    backy = self.backy()
    backy.restore(version_uid, target, sparse, force)
    backy.close()


def protect(self, version_uid):
    backy = self.backy()
    backy.protect(version_uid)
    backy.close()


def unprotect(self, version_uid):
    backy = self.backy()
    backy.unprotect(version_uid)
    backy.close()


def rm(self, version_uid, force):
    config_DEFAULTS = self.Config(section='DEFAULTS')
    disallow_rm_when_younger_than_days = int(config_DEFAULTS.get('disallow_rm_when_younger_than_days', '0'))
    backy = self.backy()
    backy.rm(version_uid, force, disallow_rm_when_younger_than_days)
    backy.close()


def scrub(self, version_uid, source, percentile):
    if percentile:
        percentile = int(percentile)
    backy = self.backy()
    state = backy.scrub(version_uid, source, percentile)
    backy.close()
    if not state:
        exit(20)


def _ls_blocks_tbl_output(self, blocks):
    tbl = PrettyTable()
    tbl.field_names = ['id', 'date', 'uid', 'size', 'valid']
    tbl.align['id'] = 'r'
    tbl.align['size'] = 'r'
    for block in blocks:
        tbl.add_row([
            block.id,
            block.date,
            block.uid,
            block.size,
            int(block.valid),
            ])
    print(tbl)

...

# version : 2.10.7
[root@localhost ~]# vim /usr/local/lib/python3.6/site-packages/backy2-2.10.7-py3.6.egg/backy2/scripts/backy.py

from backy2.config import Config as _Config
from backy2.logging import logger, init_logging
from backy2.utils import hints_from_rbd_diff, backy_from_config, convert_to_timedelta, parse_expire_date, humanize
from datetime import date, datetime
from functools import partial
from io import StringIO
from prettytable import PrettyTable
import argparse
import csv
import fileinput
import hashlib
import logging
import sys

import pkg_resources
version = pkg_resources.get_distribution('backy2').version

class Commands():
"""Proxy between CLI calls and actual backup code."""

def __init__(self, machine_output, skip_header, human_readable, Config):
    self.machine_output = machine_output
    self.skip_header = skip_header
    self.human_readable = human_readable
    self.Config = Config
    self.backy = backy_from_config(Config)


def _tbl_output(self, fields, data, alignments=None, humanize_columns=None):
    """
    outputs data based on fields list.
    fields: list(fieldnames)
    data: list of dicts with keys containing field names
    alignments: dict(name: direction)
    humanize_columns: List of columns of file sizes
    """
    tbl = PrettyTable()
    tbl.field_names = fields
    if alignments:
        for key, value in alignments.items():
            tbl.align[key] = value
    for d in data:
        values = []
        for field_name in fields:
            if type(d[field_name]) is datetime:
                **values.append(d[field_name].strftime('%Y-%m-%d %H:%M:%S'))**
            elif self.human_readable and humanize_columns and field_name in humanize_columns:
                values.append(humanize(d[field_name]))
            else:
                values.append(d[field_name])
        tbl.add_row(values)
    if self.skip_header:
        tbl.header = False
    print(tbl)


def _machine_output(self, fields, data, humanize_columns=None):
    if not self.skip_header:
        print('|'.join(fields))
    for d in data:
        values = []
        for field_name in fields:
            if type(d[field_name]) is datetime:
                **values.append(d[field_name].strftime('%Y-%m-%d %H:%M:%S'))**
            elif self.human_readable and humanize_columns and field_name in humanize_columns:
                values.append(humanize(d[field_name]))
            else:
                values.append(d[field_name])
        print('|'.join(map(str, values)))


def backup(self, name, snapshot_name, source, rbd, from_version, tag=None, expire=None):
    expire_date = None
    if expire:
        try:
            expire_date = parse_expire_date(expire)
        except ValueError as e:
            logger.error(str(e))
            exit(1)

...