Pony ORM - 解决 'Expected string or bytes-like object' 错误
Pony ORM - Resolve 'Expected string or bytes-like object' error
我目前正在 Python 中使用 Chalice 为 AWS 开发 API,它使用 Pony ORM 来处理我们的数据库。当尝试使用 select 这样的 db.select(s.start_time for s in db.Session)
进行查询时,我收到“预期的字符串或类似字节的对象”错误(下面是完整的堆栈跟踪)。但是使用这样的 lambda 进行查询 db.Session.select(lambda s: s.id = 3)
按预期工作。我不知道是什么导致了它,猜测是 db.Provider 部分在生成时不受欢迎,但我不确定 Pony 在那里期望什么。我试过使用 pdb 进行调试,但我不确定它告诉我什么。
堆栈跟踪:
Traceback (most recent call last):
File "c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\chalice\app.py", line 842, in _get_view_function_response
response = view_function(**function_args)
File "C:\Users\Gamer\Documents\AWS-SakMed\backend\SakMed\app.py", line 51, in _view_function
return wrapped(*args, **kwargs)
File "", line 2, in get_cases
File "c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py", line 528, in new_func
result = func(*args, **kwargs)
File "C:\Users\Gamer\Documents\AWS-SakMed\backend\SakMed\app.py", line 89, in get_cases
query = db.select(p.first_name for p in db.Provider)
File "c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py", line 881, in select
if not select_re.match(sql): sql = 'select ' + sql
TypeError: expected string or bytes-like object
单步执行 pdb 调试(格式有点奇怪):
c:\users\gamer\documents\aws-sakmed\backend\sakmed\app.py(89)get_cases()
-> query = db.select(p.first_name for p in db.Provider) (Pdb) step(s)
--Call-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3927)iter()
-> def iter(entity): (Pdb) c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3928)iter()
-> return EntityIter(entity) (Pdb)
--Call-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3630)init()
-> def init(self, entity): (Pdb) c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3631)init()
-> self.entity = entity (Pdb)
--Return-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3631)init()->None
-> self.entity = entity (Pdb)
--Return-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3928)iter()->
-> return EntityIter(entity) (Pdb)
--Call-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(879)select()
-> @cut_traceback (Pdb) c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(881)select()
-> if not select_re.match(sql): sql = 'select ' + sql (Pdb) pp(sql) generator object get_cases.locals.genexpr at 0x048062B0 (Pdb)
step(s) TypeError: expected string or bytes-like object
c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(881)select()
-> if not select_re.match(sql): sql = 'select ' + sql (Pdb)
相关代码:app.py
db = create_database()
datastore = DataStore(db)
def app_db_session(func):
wrapped = db_session(func)
def _view_function(*args, **kwargs):
global db_is_bound
if not db_is_bound:
debug = os.getenv('localdev')
if debug is None:
datastore.connect(host, name, password, dbname)
elif debug == 'True':
datastore.connect('localhost', 'user', 'password', 'local-db')
db_is_bound = True
return wrapped(*args, **kwargs)
return _view_function
@app.route('/recipient/{rec_id}/cases', methods=['GET'])
@app_db_session
def get_cases(rec_id):
query = db.Provider.select(lambda p: p.id == 1)
query = db.select(p.first_name for p in db.Provider))
相关代码:data_store.py
class DataStore():
def __init__(self, db):
self.db = db
def connect(self, host, user, passwd, db_name):
self.db.bind(provider='mysql', host=host, user=user, passwd=passwd, db=db_name)
self.__map_data_models()
def bind_memory(self):
self.db.bind(provider='sqlite', filename=':memory:')
self.__map_data_models()
def __map_data_models(self):
self.db.generate_mapping(create_tables=True)
相关代码:base.py
def create_database():
db = Database()
class Provider(db.Entity):
id = PrimaryKey(int, auto=True)
hsa_id = Required(str)
role = Optional(str)
available = Required(bool)
first_name = Optional(str)
last_name = Optional(str)
return db
如果要使用生成器语法,需要使用select
函数:
from pony import orm
...
query = orm.select(p for p in Person if p.name.startswith('A'))
for obj in query:
print(obj.name)
Database
对象的方法 select
用于原始 SQL 查询
from pony import orm
...
db = orm.Database('sqlite', ':memory:')
...
rows = db.select("id, name FROM person p WHERE p.name LIKE 'A%'")
for row in rows:
print(row[1])
我目前正在 Python 中使用 Chalice 为 AWS 开发 API,它使用 Pony ORM 来处理我们的数据库。当尝试使用 select 这样的 db.select(s.start_time for s in db.Session)
进行查询时,我收到“预期的字符串或类似字节的对象”错误(下面是完整的堆栈跟踪)。但是使用这样的 lambda 进行查询 db.Session.select(lambda s: s.id = 3)
按预期工作。我不知道是什么导致了它,猜测是 db.Provider 部分在生成时不受欢迎,但我不确定 Pony 在那里期望什么。我试过使用 pdb 进行调试,但我不确定它告诉我什么。
堆栈跟踪:
Traceback (most recent call last): File "c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\chalice\app.py", line 842, in _get_view_function_response response = view_function(**function_args) File "C:\Users\Gamer\Documents\AWS-SakMed\backend\SakMed\app.py", line 51, in _view_function return wrapped(*args, **kwargs) File "", line 2, in get_cases File "c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py", line 528, in new_func result = func(*args, **kwargs) File "C:\Users\Gamer\Documents\AWS-SakMed\backend\SakMed\app.py", line 89, in get_cases query = db.select(p.first_name for p in db.Provider) File "c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py", line 881, in select if not select_re.match(sql): sql = 'select ' + sql TypeError: expected string or bytes-like object
单步执行 pdb 调试(格式有点奇怪):
c:\users\gamer\documents\aws-sakmed\backend\sakmed\app.py(89)get_cases()
-> query = db.select(p.first_name for p in db.Provider) (Pdb) step(s)
--Call-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3927)iter()-> def iter(entity): (Pdb) c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3928)iter()
-> return EntityIter(entity) (Pdb)
--Call-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3630)init()-> def init(self, entity): (Pdb) c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3631)init()
-> self.entity = entity (Pdb)
--Return-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3631)init()->None-> self.entity = entity (Pdb)
--Return-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(3928)iter()->
-> return EntityIter(entity) (Pdb)
--Call-- c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(879)select()-> @cut_traceback (Pdb) c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(881)select()
-> if not select_re.match(sql): sql = 'select ' + sql (Pdb) pp(sql) generator object get_cases.locals.genexpr at 0x048062B0 (Pdb)
step(s) TypeError: expected string or bytes-like object c:\users\gamer.virtualenvs\backend-qptpobgm\lib\site-packages\pony\orm\core.py(881)select() -> if not select_re.match(sql): sql = 'select ' + sql (Pdb)
相关代码:app.py
db = create_database()
datastore = DataStore(db)
def app_db_session(func):
wrapped = db_session(func)
def _view_function(*args, **kwargs):
global db_is_bound
if not db_is_bound:
debug = os.getenv('localdev')
if debug is None:
datastore.connect(host, name, password, dbname)
elif debug == 'True':
datastore.connect('localhost', 'user', 'password', 'local-db')
db_is_bound = True
return wrapped(*args, **kwargs)
return _view_function
@app.route('/recipient/{rec_id}/cases', methods=['GET'])
@app_db_session
def get_cases(rec_id):
query = db.Provider.select(lambda p: p.id == 1)
query = db.select(p.first_name for p in db.Provider))
相关代码:data_store.py
class DataStore():
def __init__(self, db):
self.db = db
def connect(self, host, user, passwd, db_name):
self.db.bind(provider='mysql', host=host, user=user, passwd=passwd, db=db_name)
self.__map_data_models()
def bind_memory(self):
self.db.bind(provider='sqlite', filename=':memory:')
self.__map_data_models()
def __map_data_models(self):
self.db.generate_mapping(create_tables=True)
相关代码:base.py
def create_database():
db = Database()
class Provider(db.Entity):
id = PrimaryKey(int, auto=True)
hsa_id = Required(str)
role = Optional(str)
available = Required(bool)
first_name = Optional(str)
last_name = Optional(str)
return db
如果要使用生成器语法,需要使用select
函数:
from pony import orm
...
query = orm.select(p for p in Person if p.name.startswith('A'))
for obj in query:
print(obj.name)
Database
对象的方法 select
用于原始 SQL 查询
from pony import orm
...
db = orm.Database('sqlite', ':memory:')
...
rows = db.select("id, name FROM person p WHERE p.name LIKE 'A%'")
for row in rows:
print(row[1])