在Ponyorm中编写布尔转换器问题

时间:2019-05-22 13:55:19

标签: python ponyorm

我的数据库将布尔值存储为CHAR(1),T = True,F = False。我正在尝试编写一个转换器,以便可以在python代码中使用bool值,并让pony处理到数据库的转换。

这就是我所拥有的:

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 :(得分:0)

实现目标的最简单方法是使用hybrid methods

您这样做

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