После отладки скрипта + кода SqlAlchemy с помощью Eclipse я обнаружил, что список таблиц / столбцов хранится внутри в нижнем регистре. Таким образом, никогда не было возможности совпадения между EXPRESSION.foreignkey и expression.foreignkey. Отсюда и сообщение об ошибке.
Углубившись в документацию по SqlAlchemy (http://www.sqlalchemy.org/docs/reference/dialects/oracle.html#identifier-casing), я обнаружил следующее:
"В Oracle словарь данных представляет все имена символов, нечувствительные к регистру, используя текст UPPERCASE. С другой стороны, SQLAlchemy считает, что имя идентификатора всех строчных букв нечувствительно к регистру. Диалект Oracle преобразует все идентификаторы, не чувствительные к регистру, в и из них. два формата во время обмена данными на уровне схемы, такие как отображение таблиц и индексов. Использование имени UPPERCASE на стороне SQLAlchemy указывает идентификатор с учетом регистра, а SQLAlchemy будет заключать в кавычки имя - это приведет к несовпадению с данными словаря данных, полученными из Oracle, поэтому, если только Имена идентификаторов действительно созданы с учетом регистра (т. е. с использованием имен в кавычках), все строчные имена должны использоваться на стороне SQLAlchemy. "
Так что мой код работает, если он выглядит следующим образом (различия только в регистре):
from sqlalchemy import *
from sqlalchemy.orm import create_session
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
engine = create_engine('oracle://EPIGENETICS:sgc04lab@ELN')
meta = MetaData(bind=engine)
class construct(Base):
__table__ = Table('construct', meta, autoload=True)
class expression(Base):
__table__ = Table('expression', meta, autoload=True)
class purification(Base):
__table__ = Table('purification', meta, autoload=True)
session = create_session(bind=engine)
print session.query(expression).join(purification,expression)
... который выплевывает:
SELECT expression.pkey AS expression_pkey, expression.cellline AS expression_cellline, expression.epiconstruct_pkey AS expression_epiconstruct_pkey, expression.elnexp AS expression_elnexp, expression.expression_id AS expression_expression_id, expression.expressioncomments AS expression_expressioncomments, expression.cellmass AS expression_cellmass, expression.datestamp AS expression_datestamp, expression.person AS expression_person, expression.soluble AS expression_soluble, expression.semet AS expression_semet, expression.scale AS expression_scale, expression.purtest AS expression_purtest, expression.nmrlabelled AS expression_nmrlabelled, expression.yield AS expression_yield
FROM expression JOIN purification ON expression.pkey = purification.epiexpression_pkey JOIN expression ON expression.pkey = purification.epiexpression_pkey
Дело закрыто.