Python SQLAlchemy和joins,我们没有外键
在MySQL中假设以下情况:Python SQLAlchemy和joins,我们没有外键,python,mysql,join,foreign-keys,sqlalchemy,Python,Mysql,Join,Foreign Keys,Sqlalchemy,在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
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()调用的一部分:
。。。但很明显我误读了文件
提前感谢您的帮助。您有两个选择。您可以在
join
中传递连接条件,如下所示:
j = join(users, comments, onclause=users.c.id == commends.c.user_id)
如果您是根据orm.relationship
属性定义的,那么关键字参数将是primaryjoin
,而不是onclause
然而,我更喜欢的方法是撒谎。通知SQLAlchemy有外键,即使没有
comments = Table('comments', metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('users.id')),
...
)
SQLAlchemy将继续运行,就好像外键实际上存在一样,即使实际数据库没有外键。当然,如果违反了隐含的外键约束(当没有相应的
users.id
时,comments.user\u id
),您可能会遇到麻烦,但无论如何,您可能会遇到麻烦。确实要映射联接表达式吗?虽然SQLAlchemy允许这样做,但是做一些类似于session.query([Users,Comments]).join(Comments,…)
的事情可能更有意义,这样您就可以得到用户和评论模型的实例,而不是弗兰肯斯坦。此外,由于join子句没有主键,因此生成的模型没有那么有用,您无法有效地持久化对该模型的修改。我使用onclause
尝试了第一个解决方案,但遇到了TypeError
。为了解决这个问题,我删除了onclause
关键字,并将users.c.id==commissions.c.user\u id
作为参数传递。
comments = Table('comments', metadata,
Column('id', Integer, primary_key=True),
Column('user_id', Integer, ForeignKey('users.id')),
...
)