SQLAlchemy и joins, у нас нет внешних ключей
предположим следующее в MySQL:
CREATE TABLE users (
id integer auto_increment primary key,
username varchar(30),
active enum('N','Y'),
created_on int(11),
updated_on int(11),
points int(10),
// other fields
);
CREATE TABLE comments (
id integer auto_increment primary key,
user_id integer,
forum_id integer,
favorited integer,
// other fields
);
обратите внимание, что в таблицы не добавляются никакие формальные ограничения внешнего ключа. Это то, что я унаследовал и не могу изменить в нашей текущей настройке. (Мы пересматриваем всю систему, но в то же время я должен работать с тем, что мне дали)
у меня возникли проблемы с обертыванием головы вокруг соединений SQLalchemy, когда между таблицами нет формального внешнего ключа.
эффективно, я хотел бы сделать что-то вроде:
SELECT
u.username,
c.forum_id,
count(c.id)
FROM
users u
JOIN comments c ON u.id=c.user_id
WHERE
u.id = 1234
GROUP BY
u.username,
c.forum_id;
код у меня включает в себя следующие вещи:
mapper(Users, users, primary_key=[users.c.id],
include_properties=['user_id', 'username', 'active', 'created_on',
'updated_on', 'points'])
mapper(Comments, comments, primary_key=[comments.c.id],
include_properties=['active', 'user_id', 'favorited', 'forum_id'])
j = join(users, comments)
mapper(UserComments, j, properties={'user_id': [users.c.id,
comments.c.user_id]})
session = create_session()
query = session.query(UserComments).filter(users.cid == 1234)
rdata = run(query)
for row in rdata:
print row
... что, конечно, не удается с:
sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships
between 'users' and 'comments'.
Я не уверен, как обойти это, когда у нас нет внешних ключей. Как еще я могу определить отношения? Я думал, что это часть вызова mapper ():
mapper(UserComments, j, properties={'user_id': [users.c.id,
comments.c.user_id]})
... но, очевидно, я неправильно прочитал документацию.
заранее спасибо за любую помощь.
1 ответов
у вас есть два варианта. Вы можете передать условие соединения в join
вот так:
j = join(users, comments, onclause=users.c.id == commends.c.user_id)
если вы определяете это в терминах orm.relationship
свойство, параметр ключевого слова будет primaryjoin
вместо onclause
.
comments = Table('comments', metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('users.id')),
...
)
SQLAlchemy будет продолжаться, как если бы внешний ключ действительно присутствовал, даже хотя в базе данных этого нет. Конечно, вы можете столкнуться с проблемами, если будет нарушено подразумеваемое ограничение ключа foriegn (comments.user_id
когда нет соответствующего users.id
), но вы, вероятно, будете в беде в любом случае.