Я немного застрял с проблемой, связанной с SQLAlchemy и отраженными таблицами, которые связаны с внешним ключом.
У меня есть две таблицы:
result_table:
=============
| id | team_home | team_visitor | result |
| -- | --------- | ------------ | ------ |
| 1 | 1 | 2 | 3:2 |
| 2 | 1 | 3 | 2:0 |
team_table:
===========
| id | team_name |
| -- | --------- |
| 1 | Hawks |
| 2 | Sparrows |
| 3 | Eagles |
Теперь, эти таблицы уже существуют в базе данных. Я создал их с помощью PGAdmin и наполнил их образцами данных. team_home
и team_visitor
оба являются внешними ключами, указывающими на team_table.id
.
В SQLAlchemy я использую декларацию для их отражения:
from sqlalchemy import MetaData, Table, create_engine
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
database = {
...
}
engine = create_engine(URL(**database))
Base = declarative_base()
meta = MetaData()
class Results(Base):
__table__ = Table('result_table', meta, autoload=True, autoload_with=engine)
class Teams(Base):
__table__ = Table('team_table', meta, autoload=True, autoload_with=engine)
Запрос к каждой таблице не является проблемой, но я не могу присоединиться к ним. Оператор наподобие session.query(Results, Teams).join(Teams).all()
приведет к AmbiguousForeignKeysError
.
Результат должен быть:
| id | team_home | team_visitor | result |
| -- | --------- | ------------ | ------ |
| 1 | Hawks | Sparrows | 3:2 |
| 2 | Hawks | Eagles | 2:0 |
Просмотр очищенных метаданных Я вижу, что внешний ключ загружен. Теперь я застрял. Я уверен, что мне не хватает столбца в моем классе, в котором объявляются отношения (например, relationship("Address", foreign_keys=[billing_address_id])
), но, поскольку определение этого класса отражено, имена внешних ключей не доступны во время вызова (или во время создания экземпляра).
В любом случае, есть ли какие-то подсказки извне о том, как заставить внешние ключи работать в отраженных таблицах? Или лучше переопределить определение таблицы в своем классе?
Большое спасибо за ваше терпение.
С уважением, Томас
ОБНОВЛЕНИЕ
Намного проще использовать только основные функциональные возможности SQLAlchemy:
# database connection expected for this example
from sqlalchemy import MetaData
from sqlalchemy.sql import select, alias
import pandas as pd
metadata = MetaData()
metadata.reflect(bind=engine)
res_table = metadata.tables['result_table']
tt_home = metadata.tables['team_table'].alias('team_table_home')
tt_vis = metadata.tables['team_table'].alias('team_table_visitor')
s = select([
res_table.c.id,
tt_home.c.team_name,
tt_vis.c.team_name,
res_table.c.result
]).select_from(
res_table.join(
tt_home, res_table.c.team_home == tt_home.c.id
).join(
tt_vis, res_table.c.team_visitor == tt_vis.c.id)
).order_by(res_table.c.id)
result_df = pd.read_sql_query(s, engine).set_index('id')
Надеюсь, это может помочь кому-то еще, когда вы столкнетесь с объединением двух таблиц, связанных двумя внешними ключами.
Ура, Томас