Thread: [SQLObject] sqlobject one-to-many join question
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: <jo...@ma...> - 2015-12-15 23:49:35
|
So I've been absolutely loving sqlobject, until I get to actually get to making relations between tables. At this point, I feel that the 'documentation' covers some points, but really doesn't explain other bits very well at all. So I have 2 problems: The first is that when running my program the first time, it fails to create all the tables (using .createTable(ifNotExists = True)) and only several tables are generated, before it errors out with: > sqlobject.dberrors.OperationalError: Can't create table `rainmeter`.`#sql-65c_209` (errno: 150 "Foreign key constraint is incorrectly formed") Then running it again causes the rest of the tables to be created. Here's the relevant parts of my class definitions: > class Table_Sensors(sqlobject.SQLObject): > name = sqlobject.StringCol(length=32) > group = sqlobject.ForeignKey("Table_Groups") > class Table_Groups(sqlobject.SQLObject): > name = sqlobject.StringCol(length=32) > sensors = sqlobject.MultipleJoin("Table_Sensors") > Table_Sensors.createTable(ifNotExists = True) > Table_Groups.createTable(ifNotExists = True) Anyways, this is inconvenient, but it does work after running it again, so I can put up with it. The real problem I've been having is that I'm having trouble figuring out how to select all entries in Table_Sensors that point to a specific Table_Groups. Here's one example I've tried: > Table_Groups.select(Table_Groups.q.name=="Feels_Like", Table_Groups.q.sensors==Table_Sensors.q.group, orderBy=Table_Sensors.q.sort_order) But no matter what I try, even a much simpler query, It just spits back: > AttributeError: Table_Groups instance has no attribute 'sensors' As a side-note, I think some of the things I'm trying to do, I could use j-magic for, but the section on that is incredibly short, and I haven't been able to get that to work either :/ |
From: Oleg B. <ph...@ph...> - 2015-12-16 09:10:24
|
Hi! On Tue, Dec 15, 2015 at 03:49:29PM -0800, jo...@ma... wrote: > So I've been absolutely loving sqlobject, until I get to actually get to > making relations between tables. At this point, I feel that the > 'documentation' covers some points, but really doesn't explain other > bits very well at all. Patches for documentation will be gladly accepted, as well as patches for code and for tests. > So I have 2 problems: > > The first is that when running my program the first time, it fails to > create all the tables (using .createTable(ifNotExists = True)) and only > several tables are generated, before it errors out with: > > > sqlobject.dberrors.OperationalError: Can't create table `rainmeter`.`#sql-65c_209` (errno: 150 "Foreign key constraint is incorrectly formed") > > Then running it again causes the rest of the tables to be created. > > Here's the relevant parts of my class definitions: > > > class Table_Sensors(sqlobject.SQLObject): > > name = sqlobject.StringCol(length=32) > > group = sqlobject.ForeignKey("Table_Groups") > > > class Table_Groups(sqlobject.SQLObject): > > name = sqlobject.StringCol(length=32) > > sensors = sqlobject.MultipleJoin("Table_Sensors") > > Table_Sensors.createTable(ifNotExists = True) > > Table_Groups.createTable(ifNotExists = True) You create table in the wrong order. Table_Sensors has a ForeignKey pointing to to Table_Groups so you must create Table_Groups first and then Table_Sensors. > Anyways, this is inconvenient, but it does work after running it again, > so I can put up with it. The real problem I've been having is that I'm > having trouble figuring out how to select all entries in Table_Sensors > that point to a specific Table_Groups. > > Here's one example I've tried: > > > Table_Groups.select(Table_Groups.q.name=="Feels_Like", Table_Groups.q.sensors==Table_Sensors.q.group, orderBy=Table_Sensors.q.sort_order) There is a bug in the query: it lists two conditions separated by a comma. That doesn't work because the second condition becomes the second parameter for .select() instead of being a part of the condition. You must join conditions using either AND() from sqlbuilder or '&' operator: Table_Groups.select(Table_Groups.q.name=="Feels_Like" & Table_Groups.q.sensors==Table_Sensors.q.group, orderBy=Table_Sensors.q.sort_order) > But no matter what I try, even a much simpler query, It just spits back: > > > AttributeError: Table_Groups instance has no attribute 'sensors' In SQL sense Table_Groups really doesn't have an attribute 'sensors'. MultipleJoin doesn't add an attribute to SQL table. Instead it instructs SQLObject: "when the user asks for Table_Groups.sensors select rows from Table_Sensors that point to that Table_Groups' row". So this query works: Table_Groups.select(Table_Groups.q.name=="Feels_Like" & Table_Groups.q.id==Table_Sensors.q.group, orderBy=Table_Sensors.q.id) BTW, there is no need to construct an SQL query in your case -- use the power of SQLObject. If you want to select Table_Sensors for a group just fetch the group and ask for its sensors. First, let's fix the join, it should explicitly declare that it points to 'id' column in the other table: class Table_Groups(SQLObject): name = StringCol(length=32) sensors = MultipleJoin("Table_Sensors", joinColumn="id") group = Table_Groups.select(Table_Groups.q.name=='Feels_Like')[0] for sensor in group.sensors: print sensor > As a side-note, I think some of the things I'm trying to do, I could use > j-magic for, but the section on that is incredibly short, and I haven't > been able to get that to work either :/ Oleg. -- Oleg Broytman http://phdru.name/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2015-12-16 11:37:29
|
On Wed, Dec 16, 2015 at 10:10:13AM +0100, Oleg Broytman <ph...@ph...> wrote: > class Table_Groups(SQLObject): > name = StringCol(length=32) > sensors = MultipleJoin("Table_Sensors", joinColumn="id") This time it was my fault: sensors = MultipleJoin("Table_Sensors", joinColumn="group_id") > group = Table_Groups.select(Table_Groups.q.name=='Feels_Like')[0] > for sensor in group.sensors: > print sensor Oleg. -- Oleg Broytman http://phdru.name/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |