SQLAlchemy 2 外键相同的主键
我有一个带有 2 个外键的表,它们映射到另一个表的相同主键。我面临的问题是这两个外键可能是独立的值,但是,在使用 SQLAlchemy 时它们总是设置为相同的值。
表(短缺):
CREATE TABLE table1 (
userid INT NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
UNIQUE KEY(name)
);
CREATE TABLE table2 (
taskid INT NOT NULL PRIMARY KEY,
userid INT,
ownerid INT,
task VARCHAR(255) NOT NULL,
FOREIGN KEY (userid) REFERENCES users (userid),
FOREIGN KEY (ownerid) REFERENCES users (userid)
);
我正在使用 sqlalchemy 的经典映射器,我的类定义是:
class User:
def __init__( self, name ):
self.name = name
class Task:
def __init__( self, task, ownerid ):
self.task = task
self.ownerid = ownerid
ownerid 和 userid 可能不同,即ownerid 是拥有任务的用户,userid 是创建任务的用户。
我已经创建了映射:
users_table = sqlalchemy.Table( 'users', self.metadata, autoload=True )
tasks_table = sqlalchemy.Table( 'tasks', self.metadata, autoload=True )
sqlalchemy.orm.mapper( User, users_table, properties= {
'tasks': sqlalchemy.orm.relationship(Task) } )
sqlalchemy.orm.mapper( Task, tasks_table, properties {
'user': sqlalchemy.orm.relationship( User, primaryjoin=tasks_table.c.userid==users_table.c.userid ),
'owner': sqlalchemy.orm.relationship( User, primaryjoin=tasks_table.c.ownerid==users_table.c.userid ) } )
处理这些对象的语法类似于:
情况 1:
u1 = User('burt')
t1 = Task( 'buy milk', u1.userid ) # this case is that the task is assigned to self
情况 2:
u2 = User('kelly')
t2 = Task( 'review code', u1.userid ) # assign to burt, creator is kelly
在情况 2 中,我在这里遇到问题,因为所有者 ID 始终等于用户 ID,在此 在这种情况下,ownerid 和 userid 始终为 2(对于 kelly)。
i have a table with 2 foreign keys that map to the same primary key of another table. the problem i'm facing is that these two foreign keys could be independent values, however, they always get set to the same thing when using SQLAlchemy.
tables (shorthanded):
CREATE TABLE table1 (
userid INT NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
UNIQUE KEY(name)
);
CREATE TABLE table2 (
taskid INT NOT NULL PRIMARY KEY,
userid INT,
ownerid INT,
task VARCHAR(255) NOT NULL,
FOREIGN KEY (userid) REFERENCES users (userid),
FOREIGN KEY (ownerid) REFERENCES users (userid)
);
i'm using the classical mapper from sqlalchemy and my class definition is:
class User:
def __init__( self, name ):
self.name = name
class Task:
def __init__( self, task, ownerid ):
self.task = task
self.ownerid = ownerid
the ownerid and userid could be different i.e. ownerid is the user who owns the task and userid is the user that created the task.
i've created mappings:
users_table = sqlalchemy.Table( 'users', self.metadata, autoload=True )
tasks_table = sqlalchemy.Table( 'tasks', self.metadata, autoload=True )
sqlalchemy.orm.mapper( User, users_table, properties= {
'tasks': sqlalchemy.orm.relationship(Task) } )
sqlalchemy.orm.mapper( Task, tasks_table, properties {
'user': sqlalchemy.orm.relationship( User, primaryjoin=tasks_table.c.userid==users_table.c.userid ),
'owner': sqlalchemy.orm.relationship( User, primaryjoin=tasks_table.c.ownerid==users_table.c.userid ) } )
and the syntax for working with these objects is something akin to:
case 1:
u1 = User('burt')
t1 = Task( 'buy milk', u1.userid ) # this case is that the task is assigned to self
case 2:
u2 = User('kelly')
t2 = Task( 'review code', u1.userid ) # assign to burt, creator is kelly
in case 2, i'm having an issue here as the ownerid always equals the userid, in this
case the ownerid and userid are 2 (for kelly) always.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须使用 主要加入。
因此,您的代码将像
注意:当您有2个具有相同表的外键时,您必须提及哪个关系引用依赖表中的哪个文件。
可能这会解决您的问题
You have to use primaryjoin.
So your code will be change like
Note: When you have 2 foreign key with same table then you have to mention which relation is refer to which filed in the dependent table.
Might be this will solve your problem
我有一个修复:我刚刚向
Task
添加了一个owner
成员变量:然后:
I have a fix: I just added an
owner
member variable toTask
:and then:
当同一个表有多个关系时,sqlalchemy 需要更多信息来了解如何构建连接。您可以使用 primaryjoin或 foreign_keys 来实现这一点。正如 Lafada 提到的,任务关系缺少这一额外的信息。
我的代码版本没有显示您提到的问题。也许您可以检查一下这是否可以解决您的问题?
When you have more than one relationship to the same table, sqlalchemy need more information to find out how to build the join. You can use either primaryjoin or foreign_keys to achieve that. As Lafada mentioned, the Task relationship is missing this extra bit of information.
My version of your code does not display the problem you mentioned. Maybe you could check and see if this solves your problem?