SQLAlchemy和join,我们没有外键

ian*_*las 8 python mysql join sqlalchemy foreign-keys

在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
);
Run Code Online (Sandbox Code Playgroud)

请注意,没有正式的外键约束添加到表中.这是我继承的东西,不能改变我们当前的设置.(我们正在改造整个系统,但在此期间我必须与我所获得的一起工作)

当桌面之间没有建立正式的外键时,我无法绕过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;
Run Code Online (Sandbox Code Playgroud)

代码I包括以下内容:

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
Run Code Online (Sandbox Code Playgroud)

...当然失败了:

sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships
between 'users' and 'comments'.
Run Code Online (Sandbox Code Playgroud)

当我们没有外键时,我不确定如何解决这个问题.我怎么定义这种关系?我认为它是mapper()调用的一部分:

mapper(UserComments, j, properties={'user_id': [users.c.id, 
    comments.c.user_id]})
Run Code Online (Sandbox Code Playgroud)

......但显然我误读了文档.

在此先感谢您的帮助.

Sin*_*ion 25

你有两个选择.您可以join像这样传递连接条件:

j = join(users, comments, onclause=users.c.id == commends.c.user_id)
Run Code Online (Sandbox Code Playgroud)

如果您根据orm.relationship属性定义此属性,则关键字参数将primaryjoin代替onclause.

但是,我喜欢的方法就是撒谎.告诉SQLAlchemy有一个外键,即使没有. 

comments = Table('comments', metadata,
    Column('id', Integer, primary_key=True),
    Column('user_id', Integer, ForeignKey('users.id')),
    ...
)
Run Code Online (Sandbox Code Playgroud)

SQLAlchemy将继续进行,就好像外键实际存在一样,即使实际的数据库没有.当然,如果违反隐含的foriegn键约束(comments.user_id当没有相应的约束时users.id),你可能会遇到麻烦,但无论如何你可能会遇到麻烦.