Я пытаюсь адаптировать некоторую часть приложения MySQLdb к sqlalchemy в декларативной базе. Я только начинаю с sqlalchemy.sqlalchemy: union query несколько столбцов из нескольких таблиц с условием
наследие таблиц определены что-то вроде:
student: id_number*, semester*, stateid, condition, ...
choice: id_number*, semester*, choice_id, school, program, ...
У нас есть 3 таблицы для каждого из них (student_tmp
, student_year
, student_summer
, choice_tmp
, choice_year
, choice_summer
), так что каждая пара (_tmp
, _year
, _summer
) содержит информацию для определенного момента.
select *
from `student_tmp`
inner join `choice_tmp` using (`id_number`, `semester`)
Моя проблема заключается в том, что информация важна для меня, чтобы получить эквивалент следующее: выберите
SELECT t.*
FROM (
(
SELECT st.*, ct.*
FROM `student_tmp` AS st
INNER JOIN `choice_tmp` as ct USING (`id_number`, `semester`)
WHERE (ct.`choice_id` = IF(right(ct.`semester`, 1)='1', '3', '4'))
AND (st.`condition` = 'A')
) UNION (
SELECT sy.*, cy.*
FROM `student_year` AS sy
INNER JOIN `choice_year` as cy USING (`id_number`, `semester`)
WHERE (cy.`choice_id` = 4)
AND (sy.`condition` = 'A')
) UNION (
SELECT ss.*, cs.*
FROM `student_summer` AS ss
INNER JOIN `choice_summer` as cs USING (`id_number`, `semester`)
WHERE (cs.`choice_id` = 3)
AND (ss.`condition` = 'A')
)
) as t
*
используется для укоротить выбора, но я на самом деле запрашивая только о 7 столбцов из 50 доступных.
Эта информация используется во многих вариантах ... «У меня есть новые ученики? У меня все еще есть ученики с определенной даты? Какие ученики подписаны после указанной даты? И т. Д.». Результат этого select должен быть сохранен в другой базе данных.
Можно ли достичь этого с помощью одного класса, подобного виду? Информация доступна только для чтения, поэтому мне не нужно изменять/создавать/делить. Или мне нужно объявлять класс для каждой таблицы (заканчивая 6 классами), и каждый раз, когда мне нужно запрашивать, я должен помнить, что нужно фильтровать?
Спасибо за указатели.
EDIT: У меня нет доступа к модификации базы данных (я не могу создать представление). Обе базы данных могут быть не на одном сервере (поэтому я не могу создать представление на моем втором БД).
Моя забота состоит в том, чтобы избежать полного сканирования таблицы перед фильтрацией на condition
и choice_id
.
EDIT 2: Я настроил декларативных классы, как это:
class BaseStudent(object):
id_number = sqlalchemy.Column(sqlalchemy.String(7), primary_key=True)
semester = sqlalchemy.Column(sqlalchemy.String(5), primary_key=True)
unique_id_number = sqlalchemy.Column(sqlalchemy.String(7))
stateid = sqlalchemy.Column(sqlalchemy.String(12))
condition = sqlalchemy.Column(sqlalchemy.String(3))
class Student(BaseStudent, Base):
__tablename__ = 'student'
choices = orm.relationship('Choice', backref='student')
#class StudentYear(BaseStudent, Base):...
#class StudentSummer(BaseStudent, Base):...
class BaseChoice(object):
id_number = sqlalchemy.Column(sqlalchemy.String(7), primary_key=True)
semester = sqlalchemy.Column(sqlalchemy.String(5), primary_key=True)
choice_id = sqlalchemy.Column(sqlalchemy.String(1))
school = sqlalchemy.Column(sqlalchemy.String(2))
program = sqlalchemy.Column(sqlalchemy.String(5))
class Choice(BaseChoice, Base):
__tablename__ = 'choice'
__table_args__ = (
sqlalchemy.ForeignKeyConstraint(['id_number', 'semester',],
[Student.id_number, Student.semester,]),
)
#class ChoiceYear(BaseChoice, Base): ...
#class ChoiceSummer(BaseChoice, Base): ...
Теперь запрос, который дает мне правильный SQL для одного набора таблицы:
q = session.query(StudentYear, ChoiceYear) \
.select_from(StudentYear) \
.join(ChoiceYear) \
.filter(StudentYear.condition=='A') \
.filter(ChoiceYear.choice_id=='4')
но он выдает исключение ...
"Could not locate column in row for column '%s'" % key)
sqlalchemy.exc.NoSuchColumnError: "Could not locate column in row for column '*'"
Как использовать этот запрос создать себе класс, который я могу использовать?
Что такое 'модель Social' ссылается FK из' Choice'? – van
Извините, это должен быть Студент, обновленный. – Danosaure