Преобразование даты и Any() в Pony ORM с SQLitePython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Преобразование даты и Any() в Pony ORM с SQLite

Сообщение Anonymous »

Я создаю учебное пособие по веб-приложению с использованием Pony ORM. Мой Python работает, но кажется очень неуклюжим: в частности, я управляю преобразованием дат вручную после выборки записей и выполняю строковые операции объединения, а затем разделения для обработки отношений «один ко многим», где я, естественно, использовал бы Поле JSON. Схема БД, объекты Pony, мой запрос и мой код преобразования приведены ниже; Буду очень признателен за советы, как это упростить.
Схема базы данных
В этой базе данных отслеживается, какие сотрудники какие эксперименты проводили ( «многие ко многим»), какие экспериментальные пластины в каких экспериментах участвуют (многие к одному) и какие из этих пластин признаны недействительными (необязательно «один к одному»).

Код: Выделить всё

-- staff members: staff_id is primary key
CREATE TABLE staff (
staff_id BIGINT,
personal TEXT,
family TEXT
);

-- experiments: sample_id is primary key
CREATE TABLE experiment (
sample_id BIGINT,
kind TEXT,
start TEXT,
"end" TEXT -- may be NULL if the experiment is ongoing
);

-- join table showing which staff were involved in which experiment
-- there is at least one staff member associated with every experiment
CREATE TABLE performed (
staff_id BIGINT,
sample_id BIGINT
);

-- plate_id is primary key; plate-to-experiment is many to one
- there is at least one plate associated with each experiment
CREATE TABLE plate (
plate_id BIGINT,
sample_id BIGINT,
date TEXT,
filename TEXT
);

-- invalidated plates (along with who invalidated the plate and when)
-- this table only contains records for plates that have been invalidated,
-- and contains at most one such record for each plate
CREATE TABLE invalidated (
plate_id BIGINT,
staff_id BIGINT,
date TEXT
);
Классы сущностей
Это просто, учитывая приведенные выше определения таблиц.

Код: Выделить всё

class Staff(DB.Entity):
staff_id = orm.PrimaryKey(int)
personal = orm.Required(str)
family = orm.Required(str)
performed = orm.Set("Performed")
invalidated = orm.Set("Invalidated")

class Experiment(DB.Entity):
sample_id = orm.PrimaryKey(int)
kind = orm.Required(str)
start = orm.Required(str)
end = orm.Optional(str)
performed = orm.Set("Performed")
plate = orm.Set("Plate")

class Performed(DB.Entity):
staff_id = orm.Required(Staff)
sample_id = orm.Required(Experiment)
orm.PrimaryKey(staff_id, sample_id)

class Plate(DB.Entity):
plate_id = orm.PrimaryKey(int)
sample_id = orm.Required(Experiment)
date = orm.Required(date)
filename = orm.Required(str)
invalidated = orm.Set("Invalidated")

class Invalidated(DB.Entity):
plate_id = orm.Required(Plate)
staff_id = orm.Required(Staff)
date = orm.Required(date)
orm.PrimaryKey(plate_id, staff_id)
Мой проблемный запрос
Мне нужно следующее для каждого эксперимента:
  • идентификатор эксперимента (чтобы я мог создать гиперссылку на страницу эксперимента)
  • даты начала и окончания (опять же, дата окончания может быть нет, если эксперимент продолжается)
  • есть ли в эксперименте какие-либо недействительные таблички
  • идентификаторы и имена всех сотрудников, участвовавших в эксперименте
Я обнаружил следующее:

[*]Первые три поля (идентификатор, дата начала и дата окончания) легко получить, но мне нужно преобразовать два поля даты из текста в объекты даты Python после получения значений: у Pony есть функция str2date, но, похоже, нет способа использовать это внутри запроса. (Попытка сделать это приводит к появлению сообщений об ошибках.)
[*]Я ожидал, что функции Any() и all() будут работать вместе с функцией count() Pony, sum() и другие функции агрегирования, но они, похоже, не существуют, и Pony отказывается от использования встроенных функций. Поэтому я использую count() > 0, чтобы ответить на вопрос: «Были ли какие-либо пластины в этом эксперименте признаны недействительными?»
[*]Поскольку в работе могут участвовать несколько сотрудников В рамках одного эксперимента я создаю строку с идентификатором каждого сотрудника, личными именами и фамилиями, а затем использую Pony group_concat(), чтобы объединить их и получить одну строку в результате запроса. Затем я выполняю постобработку (удаляю, разделяю и преобразую идентификатор обратно в целое число). Я понимаю, что это действительно может быть необходимо, поскольку Pony не поддерживает вложенные поля (т. е., похоже, не может создавать результаты JSON), но я надеюсь, что есть более простой способ.

Код: Выделить всё

def experiment_details():
query = orm.select(
(
e.sample_id,
e.start,
e.end,
orm.count(e.plate.invalidated) != 0,
orm.group_concat(
f""
for s in Staff
if e.sample_id in s.performed.sample_id.sample_id
),
)
for e in Experiment
)
rows = list(query.order_by(lambda eid, start, end, inv, staff: eid))
reformatters = (_reformat_as_is, _reformat_date, _reformat_date, _reformat_as_is, _reformat_staff)
rows = [[f(r) for (f, r) in zip(reformatters, row)] for row in rows]
return rows

def _reformat_as_is(text):
"""Do not reformat (used for uniform zipping)."""
return text

def _reformat_date(text):
"""Reformat possibly-empty date."""
return None if text is None else str2date(text)

def _reformat_staff(text):
"""Convert concatenated staff information back to list of tuples."""
fields = text.lstrip("").split(">,

Подробнее здесь: [url]https://stackoverflow.com/questions/78829629/date-conversion-and-any-in-pony-orm-with-sqlite[/url]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • $ route ['wranswer-qb/(: any)/(: any)/(: any)'] не работает
    Anonymous » » в форуме Php
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • Как «ВЫБРАТЬ *...» (выбрать ВСЕ) в Pony ORM?
    Anonymous » » в форуме Python
    0 Ответы
    51 Просмотры
    Последнее сообщение Anonymous
  • Набрать приверженность с помощью параметра или args (`` callable [p, any] | Callable [[], any] `)
    Anonymous » » в форуме Python
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • Набрать приверженность с помощью параметра или args (`` callable [p, any] | Callable [[], any] `)
    Anonymous » » в форуме Python
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous
  • Набрать приверженность с помощью параметра или args (`` callable [p, any] | Callable [[], any] `)
    Anonymous » » в форуме Python
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»