Проблема написания bool конвертера в понырем - PullRequest
0 голосов
/ 22 мая 2019

Моя база данных хранит значения bool как CHAR (1), T = True, F = False. Я пытаюсь написать конвертер, чтобы я мог использовать значения bool в своем коде Python и пони обрабатывать преобразование в базу данных.

Вот что у меня есть:

from pony import orm
from pony.orm.dbapiprovider import BoolConverter

class DALBoolConverter(BoolConverter):
    def validate(self, val, obj=None):
        print 'VALIDATOR', val, obj
        return val

    def py2sql(self, val):
        print 'py2sql', val
        return 'T' if val else 'F'

    def sql2py(self, val):
        print 'sql2py', val
        return True if val == 'T' else False

    def sql_type(self):
        print 'sql_type'
        return 'CHAR(1)'

db.provider.converter_classes.append((bool, DALBoolConverter))

class AuthUser(db.Entity):
    _table_ = 'auth_user'

    first_name = orm.Required(str)
    last_name = orm.Required(str)
    email = orm.Optional(str)
    password = orm.Optional(str)
    registration_key = orm.Optional(str)
    reset_password_key = orm.Optional(str)
    registration_id = orm.Optional(str)
    active = orm.Required(bool)

if __name__ == '__main__':
    with db_session:
        a = AuthUser[1]
        print a.active  #  returns True
        a.active = False

Вы можете видеть, что у меня есть некоторые операторы печати, но они никогда не выполняются. Я получаю следующую трассировку:

Traceback (most recent call last):
  File "/home/jim/dev/qlf/qlf/pony_model.py", line 720, in <module>
    """
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 476, in __exit__
    db_session._commit_or_rollback(exc_type, exc, tb)
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 490, in _commit_or_rollback
    commit()
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 381, in commit
    rollback_and_reraise(sys.exc_info())
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 370, in rollback_and_reraise
    reraise(*exc_info)
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 379, in commit
    cache.flush()
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 1888, in flush
    if obj is not None: obj._save_()
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 5363, in _save_
    elif status == 'modified': obj._save_updated_()
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 5272, in _save_updated_
    cursor = database._exec_sql(sql, arguments, start_transaction=True)
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 945, in _exec_sql
    connection = cache.reconnect(e)
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 1776, in reconnect
    if not provider.should_reconnect(exc): reraise(*sys.exc_info())
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/core.py", line 943, in _exec_sql
    try: new_id = provider.execute(cursor, sql, arguments, returning_id)
  File "<auto generated wrapper of execute() function>", line 2, in execute
  File "/home/jim/.local/lib/python2.7/site-packages/pony/orm/dbapiprovider.py", line 61, in wrap_dbapi_exceptions
    raise OperationalError(e)
pony.orm.dbapiprovider.OperationalError: (1292, "Truncated incorrect DOUBLE value: 'T  '")

... что, вероятно, имеет смысл, потому что я не думаю, что мой DALBoolConverter когда-либо вызывается.

Есть указатели?

1 Ответ

0 голосов
/ 22 мая 2019

Самый простой способ достичь своей цели - использовать гибридные методы .

Итак, вы делаете

class AuthUser(db.Entity):
    _table_ = 'auth_user'

    first_name = orm.Required(str)
    last_name = orm.Required(str)
    email = orm.Optional(str)
    password = orm.Optional(str)
    registration_key = orm.Optional(str)
    reset_password_key = orm.Optional(str)
    registration_id = orm.Optional(str)
    active = orm.Required(str) # use str here

    @propery
    def is_active(self):
        return self.active == 'T'

Тогда вы можете использовать

with db_session:
    a = AuthUser[1]
    print a.is_active 
...