Pony ORM - Устранить ошибку «Ожидаемая строка или байтовоподобный объект» - PullRequest
0 голосов
/ 06 марта 2019

В настоящее время я разрабатываю API для AWS с Chalice на Python, который использует Pony ORM для обработки нашей базы данных. При попытке выполнить запрос с помощью выбора, подобного этому db.select(s.start_time for s in db.Session), я получаю сообщение об ошибке «Ожидаемая строка или байтовоподобный объект» (полная трассировка стека ниже). Однако запросы с использованием лямбда-выражения, подобного этому db.Session.select(lambda s: s.id = 3), работают как положено. I Я в растерянности из-за того, что может быть причиной этого, предположение может быть, что часть db.Provider не нравится при генерации, но я не уверен, что Pony ожидает там. Я пытался отладить с pdb, но я я не уверен, что он говорит мне.

Трассировка стека:

Traceback (последний вызов был последним): Файл "c: \ users \ gamer.virtualenvs \ backend-qptpobgm \ lib \ site-packages \ chalice \ app.py", строка 842, в _get_view_function_response response = view_function (** function_args) Файл "C: \ Users \ Gamer \ Documents \ AWS-SakMed \ backend \ SakMed \ app.py", строка 51, в _view_function возврат завернутый (* args, ** kwargs) Файл "", строка 2, в get_cases Файл "c: \ users \ gamer.virtualenvs \ backend-qptpobgm \ lib \ site-packages \ pony \ orm \ core.py", строка 528, в new_func результат = func (* args, ** kwargs) Файл "C: \ Users \ Gamer \ Documents \ AWS-SakMed \ backend \ SakMed \ app.py", строка 89, в get_cases query = db.select (p.first_name для p в db.Provider) Файл "c: \ users \ gamer.virtualenvs \ backend-qptpobgm \ lib \ site-packages \ pony \ orm \ core.py", строка 881, в select если нет select_re.match (sql): sql = 'select' + sql Ошибка типа: ожидаемая строка или байтовоподобный объект

Переход отладки к pdb (форматирование немного странное):

C: \ Users \ геймер \ документы \ AWS-sakmed \ Серверные \ sakmed \ app.py (89) get_cases ()

-> query = db.select (p.first_name для p в db.Provider) (Pdb) шаг (ы)
--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) иТЭР ()

-> вернуть 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 () -> Нет

-> self.entity = entity (Pdb)
--Return-- c: \ users \ gamer.virtualenvs \ backend-qptpobgm \ lib \ site-packages \ pony \ orm \ core.py (3928) iter () ->
-> вернуть 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 ()

-> если нет select_re.match (sql): sql = 'select' + sql (Pdb) pp (sql) объект генератора get_cases.locals.genexpr по адресу 0x048062B0 (Pdb)
step (s) TypeError: ожидаемая строка или байтовоподобный объект C: \ Users \ gamer.virtualenvs \ бэкенд-qptpobgm \ Lib \ сайт-пакеты \ лошадка \ ORM \ core.py (881) выберите () -> если нет 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

1 Ответ

1 голос
/ 15 марта 2019

Если вы хотите использовать синтаксис генератора, вам нужно использовать функцию 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)

Метод select из Database объекта используется для необработанных запросов 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])
...