[sqlalchemy] Interpretation of SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'...
I'm getting an SAWarning (0.6.4 and also 0.7b5dev) which has a message that confuses me, so I've duplicated the problem with a script: === from sqlalchemy import * from sqlalchemy.orm import * engine = create_engine('sqlite:///', echo=True) metadata = MetaData(engine) session = sessionmaker(bind=engine)() # association table post_keywords = Table('post_keywords', metadata, Column('post_id', Integer, ForeignKey('posts.id')), Column('keyword_id', Integer, ForeignKey('keywords.id')) ) posts_table = Table('posts', metadata, Column('id', Integer, primary_key=True), Column('headline', String(255), nullable=False), Column('body', Text) ) keywords_table = Table('keywords', metadata, Column('id', Integer, primary_key=True), Column('keyword', String(50), nullable=False, unique=True) ) spotlights_table = Table('spotlights', metadata, Column('id', Integer, primary_key=True), Column('enddate', Date), Column('post_id', Integer, ForeignKey('posts.id')) ) class BlogPost(object): def __init__(self, headline, body): self.headline = headline self.body = body def __repr__(self): return BlogPost(%r, %r, %r) % (self.headline, self.body, self.author) class Keyword(object): def __init__(self, keyword): self.keyword = keyword class PostSpotLight(object): pass mapper(Keyword, keywords_table) mapper(BlogPost, posts_table, properties = {'keywords': relationship(Keyword, secondary=post_keywords, backref='posts')} ) mapper(PostSpotLight, spotlights_table, properties = {'postkeywords': relationship(Keyword, secondary=post_keywords, primaryjoin=spotlights_table.c.post_id==post_keywords.c.post_id)} ) metadata.create_all(engine) compile_mappers() = Here is the warning: [...]/sqlalchemy-default/lib/sqlalchemy/orm/properties.py:900: SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'. Assumed referenced foreign key columns 'post_keywords.keyword_id', 'post_keywords.post_id' for join condition 'spotlights.post_id = post_keywords.post_id' on relationship PostSpotLight.postkeywords eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) Why is the complaint that there are No ForeignKey objects were present in secondary table 'post_keywords', when clearly there are? ***Furthermore, if I pass the relationship this: foreign_keys=[post_keywords.c.post_id,post_keywords.c.keyword_id] then the warning goes away, but all I've done is specify the very foreign_keys that already exist.*** (I realize now I could also use an association proxy for the keywords via the post, but the question remains.) Thanks as always, Kent -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
[sqlalchemy] API that allows me to do additional database operations just before insert execution for SQL Expression
Is there any API that allows me do some processing (I want to do additional updates based on the insert statement) just before executing an insert statement using SQL Expression? I dont want to do this during compile time (@Compiles(Insert)) as I will be doing some database updates and this is not desirable for every compilation e.g., just a simple print should not do this additional processing. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
RE: [sqlalchemy] API that allows me to do additional database operations just before insert execution for SQL Expression
-Original Message- From: sqlalchemy@googlegroups.com [mailto:sqlalchemy@googlegroups.com] On Behalf Of bool Sent: 19 April 2011 14:16 To: sqlalchemy Subject: [sqlalchemy] API that allows me to do additional database operations just before insert execution for SQL Expression Is there any API that allows me do some processing (I want to do additional updates based on the insert statement) just before executing an insert statement using SQL Expression? I dont want to do this during compile time (@Compiles(Insert)) as I will be doing some database updates and this is not desirable for every compilation e.g., just a simple print should not do this additional processing. SA 0.7 generates events both at the ORM level and at the SQL level. See: http://www.sqlalchemy.org/docs/07/core/event.html http://www.sqlalchemy.org/docs/07/core/events.html For example, there is a 'before_execute' event which you could listen for, and look for INSERT clauses. If you can't upgrade to 0.7, you might be able to use a ConnectionProxy: http://www.sqlalchemy.org/docs/07/core/interfaces.html Hope that helps, Simon -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Support for tuple expressions?
there's a tuple_() operator: http://www.sqlalchemy.org/docs/core/expression_api.html?highlight=tuple_#sqlalchemy.sql.expression.tuple_ the object returns is _Tuple. if you wanted fancy per-dialect expression behavior, mmm tricky, you'd need to subclass _Tuple (or write a new object), intercept comparisons like __eq__(), then return *another* construct that represents a Tuple Comparison, and that object would need per-dialect compilation rules. or you could lobby the sqlite folks to add support for the construct in the first place.though i doubt SQL Server has it either. On Apr 18, 2011, at 4:57 PM, bukzor wrote: SQL-92 defines a row value constructor expression like (1,2,3) which looks and behaves exactly like a Python tuple, as far as I can tell. These are implemented correctly in mysql at least, and I believe PostgreSQL and Oracle as well, although I don't have access to those systems. What would be the best way to deal with this type of value in SQLAlchemy? Should I create a RowValue class which can be visited by the various dialects? If I wanted to provide emulation for dialects which don't directly support this standard, what would be the way to go? For example, I'd like to be able to expand RowValue((1,2)) = RowValue(colA, colB) to 1 colA or (1=colA and 2 = ColB) under sqlite. --Buck -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Interpretation of SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'...
On Apr 19, 2011, at 9:04 AM, Kent wrote: I'm getting an SAWarning (0.6.4 and also 0.7b5dev) which has a message that confuses me, so I've duplicated the problem with a script: === mapper(PostSpotLight, spotlights_table, properties = {'postkeywords': relationship(Keyword, secondary=post_keywords, primaryjoin=spotlights_table.c.post_id==post_keywords.c.post_id)} ) [...]/sqlalchemy-default/lib/sqlalchemy/orm/properties.py:900: SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'. Assumed referenced foreign key columns 'post_keywords.keyword_id', 'post_keywords.post_id' for join condition 'spotlights.post_id = post_keywords.post_id' on relationship PostSpotLight.postkeywords eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) Why is the complaint that there are No ForeignKey objects were present in secondary table 'post_keywords', when clearly there are? Well this is the message knowing something was wrong but not expressing it in a way that I expected when I wrote it. post_keywords has no foreign keys that refer to the spotlights table.if a primaryjoin condition is given, it only cares about foreign keys that express components of the join condition. this used to be an error condition but eventually I figured that things would just work if I assumed the cols in post_keywords were FKs, after I saw someone confused by placing a secondary table that in fact had no FKs on it. ***Furthermore, if I pass the relationship this: foreign_keys=[post_keywords.c.post_id,post_keywords.c.keyword_id] then the warning goes away, but all I've done is specify the very foreign_keys that already exist.*** well in this case you give it some columns, but not what they reference to. So it sees post_id and it says, oh, thats the FK that points to spotlights.post_id. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Interpretation of SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'...
So, what would you suggest the right answer is in this case? In the real world scenario we have a potentially good reason to avoid the association proxy approach since that involves an additional table which may be unneeded. Is the best answer just to provide the foreign keys as I did? On 4/19/2011 11:47 AM, Michael Bayer wrote: On Apr 19, 2011, at 9:04 AM, Kent wrote: I'm getting an SAWarning (0.6.4 and also 0.7b5dev) which has a message that confuses me, so I've duplicated the problem with a script: === mapper(PostSpotLight, spotlights_table, properties = {'postkeywords': relationship(Keyword, secondary=post_keywords, primaryjoin=spotlights_table.c.post_id==post_keywords.c.post_id)} ) [...]/sqlalchemy-default/lib/sqlalchemy/orm/properties.py:900: SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'. Assumed referenced foreign key columns 'post_keywords.keyword_id', 'post_keywords.post_id' for join condition 'spotlights.post_id = post_keywords.post_id' on relationship PostSpotLight.postkeywords eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) Why is the complaint that there are No ForeignKey objects were present in secondary table 'post_keywords', when clearly there are? Well this is the message knowing something was wrong but not expressing it in a way that I expected when I wrote it. post_keywords has no foreign keys that refer to the spotlights table.if a primaryjoin condition is given, it only cares about foreign keys that express components of the join condition. this used to be an error condition but eventually I figured that things would just work if I assumed the cols in post_keywords were FKs, after I saw someone confused by placing a secondary table that in fact had no FKs on it. ***Furthermore, if I pass the relationship this: foreign_keys=[post_keywords.c.post_id,post_keywords.c.keyword_id] then the warning goes away, but all I've done is specify the very foreign_keys that already exist.*** well in this case you give it some columns, but not what they reference to. So it sees post_id and it says, oh, thats the FK that points to spotlights.post_id. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Interpretation of SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'...
On Apr 19, 2011, at 12:57 PM, Kent Bower wrote: So, what would you suggest the right answer is in this case? In the real world scenario we have a potentially good reason to avoid the association proxy approach since that involves an additional table which may be unneeded. Is the best answer just to provide the foreign keys as I did? it is ! or just have the warning, its not a big deal. id make sure viewonly=True is set as well. On 4/19/2011 11:47 AM, Michael Bayer wrote: On Apr 19, 2011, at 9:04 AM, Kent wrote: I'm getting an SAWarning (0.6.4 and also 0.7b5dev) which has a message that confuses me, so I've duplicated the problem with a script: === mapper(PostSpotLight, spotlights_table, properties = {'postkeywords': relationship(Keyword, secondary=post_keywords, primaryjoin=spotlights_table.c.post_id==post_keywords.c.post_id)} ) [...]/sqlalchemy-default/lib/sqlalchemy/orm/properties.py:900: SAWarning: No ForeignKey objects were present in secondary table 'post_keywords'. Assumed referenced foreign key columns 'post_keywords.keyword_id', 'post_keywords.post_id' for join condition 'spotlights.post_id = post_keywords.post_id' on relationship PostSpotLight.postkeywords eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) Why is the complaint that there are No ForeignKey objects were present in secondary table 'post_keywords', when clearly there are? Well this is the message knowing something was wrong but not expressing it in a way that I expected when I wrote it. post_keywords has no foreign keys that refer to the spotlights table.if a primaryjoin condition is given, it only cares about foreign keys that express components of the join condition. this used to be an error condition but eventually I figured that things would just work if I assumed the cols in post_keywords were FKs, after I saw someone confused by placing a secondary table that in fact had no FKs on it. ***Furthermore, if I pass the relationship this: foreign_keys=[post_keywords.c.post_id,post_keywords.c.keyword_id] then the warning goes away, but all I've done is specify the very foreign_keys that already exist.*** well in this case you give it some columns, but not what they reference to. So it sees post_id and it says, oh, thats the FK that points to spotlights.post_id. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
[sqlalchemy] Oracle column names beginning with a digit
Hi, I have a little problem with column names that start with a digit at an oracle databases which I inherited. When I try to do and update/insert with values from a dict like this i.e.: ---8-- engine =create_engine('oracle+cx_oracle://foobar') engine.echo = True Session = sessionmaker(bind=engine) session = Session() metadata = MetaData() metadata.bind = engine site_tbl = Table('TBL_SITE', metadata, autoload = True, schema='foo' ) pks = {'Site_Id':5772} vals= {'100K_Name':'Foo','Accuracy':'Bar'} clauses = [site_tbl.c[k]==v for k,v in pks.iteritems()] update = site_tbl.update().where(and_(*clauses)) session.execute(update,vals) session.commit() ---8--- I get this error: ---8--- DatabaseError: (DatabaseError) ORA-01036: illegal variable name/number 'UPDATE foo.TBL_SITE SET 100K_Name=:100K_Name, Accuracy_Method=:Accuracy_Method WHERE foo.TBL_SITE.Site_Id = :Site_Id_1' {'Site_Id_1': 5772, '100K_Name': 'Foo', 'Accuracy': 'Bar'} ---8--- The problem is that the bindname ':100K_Name'. Something like this: ---8--- myupdate='UPDATE foo.TBL_SITE SET 100K_Name=:bv0, Accuracy=:Accuracy_Method WHERE Site_Id = :Site_Id' myvals={'Site_Id':5772,'Accuracy_Method ':'Bar','bv0':'Foo'} session.execute(text(myupdate),myvals) ---8--- works fine but I really would like to know if there is a way to let SA handle these column names binds automatically? ( It would make things a lot easier for me as the vals dict is generated dynamically. ) Kind Regards, Sirko -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
Re: [sqlalchemy] Oracle column names beginning with a digit
On Apr 19, 2011, at 9:55 PM, Sirko Schroeder wrote: Hi, I have a little problem with column names that start with a digit at an oracle databases which I inherited. When I try to do and update/insert with values from a dict like this i.e.: site_tbl = Table('TBL_SITE', metadata, autoload = True, schema='foo' ) pks = {'Site_Id':5772} vals= {'100K_Name':'Foo','Accuracy':'Bar'} clauses = [site_tbl.c[k]==v for k,v in pks.iteritems()] update = site_tbl.update().where(and_(*clauses)) session.execute(update,vals) session.commit() ---8--- I get this error: ---8--- DatabaseError: (DatabaseError) ORA-01036: illegal variable name/number 'UPDATE foo.TBL_SITE SET 100K_Name=:100K_Name, Accuracy_Method=:Accuracy_Method WHERE foo.TBL_SITE.Site_Id = :Site_Id_1' {'Site_Id_1': 5772, '100K_Name': 'Foo', 'Accuracy': 'Bar'} yeah that is pretty awful, Oracle is super picky about names, and there's already a lot of stuff to appease its limitations with bind parameters. The bind name is ultimately derived from the key of the column so this would change the name: Table(my_table, metadata, Column(100K_Name, String, key=hundredkname), autoload=True) if you want something more automated than that you can use 0.7 and redefine the names with events, docs for that are at http://www.sqlalchemy.org/docs/07/core/events.html#sqlalchemy.events.DDLEvents.column_reflect . beyond using the key thing, which changes how you reference the column object in Python, we'd have to dig into the core and handle this case. if quoting the bind name is enough that would make it an easier adjustment. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
[sqlalchemy] Re: Error with Adjacency List Relationship Implementation
Figured it out, I was being retarded. Thanks! On Apr 19, 7:33 pm, Aviv Giladi avivgil...@gmail.com wrote: Hey guys, I am playing around with SQLAlchemy (over Pylons) and encountering a strange problem. I am using the adjacency list relationship concept to represent nodes and their parents in a single table. I copied exactly this code from the examples: class Node(Base): __tablename__ = 'nodes' id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('nodes.id')) data = Column(Unicode(50)) children = relationship('Node', cascade=all, backref=backref(parent, remote_side='Node.id'), # tried with and without this: collection_class=attribute_mapped_collection('data'), ) My test is basically adding two nodes, like so: n = Node() n.id = 1 n.parent_id = 0 n.data = 'parent' n2 = Node() n2.id = 2 n2.parent_id = 1 n2.data = 'child' Session.add(n) Session.add(n2) Session.commit() When I run my test, I get the following exception raised from connections.py: sqlalchemy.exc.IntegrityError: (IntegrityError) (1452, 'Cannot add or update a child row: a foreign key constraint fails (`db`.`nodes`, CONSTRAINT `nodes_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `nodes` (`id`))') 'INSERT INTO nodes (id, parent_id, data) VALUES (%s, %s, %s)' (1, 0, 'parent') Please, what am I missing here? Thanks! -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
[sqlalchemy] Self-referencing Table Cannot Have 0 as Primary Index?
Hey guys, I encountered a very strange problem with SQLAlchemy. I have a model that is self-referencing (adjacency list relationship). I simply copied the model (Node) from the SQLAlchemy tutorial. Here is the model's code: class Node(Base): __tablename__ = 'nodes' id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('nodes.id')) parent = Column(Unicode(50)) children = relationship('Node', cascade=all, #tried to remove this backref=backref(parent, remote_side='Node.id'), collection_class=attribute_mapped_collection('data'), #tried to remove this as well ) I reproduced the problem within my controllers, but I also ran this test (after fully loading my environment of course): parent = Node() parent.id = 1 parent.parent_id = None parent.name = 'parent' Session.add(parent) child = Node() child.id = 20 child.parent_id = 1 child.name = 'child' Session.add(child) Session.commit() The above code works just fine (the changes are successfully committed and reflected in the DB). The problem arises when I change the `parent` node's id to 0 (and the `child`'s parent_id to 0 accordingly). Then, I get the following exception: .. File C:\Python26\Lib\site-packages\MySQLdb\connections.py, line 36, in defaulterrorhandler raise errorclass, errorvalue sqlalchemy.exc.IntegrityError: (IntegrityError) (1452, 'Cannot add or update a child row: a foreign key constraint fails (`db`.`nodes`, CONSTRAINT `nodes_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `nodes` (`id`))') 'INSERT INTO nodes (id, parent_id, name) VALUES (%s, %s, %s)' (20, 0, 'child') Surprisingly, changing this value (the `node`'s id and the `child`'s parent_id) to _anything_ but 0 (-5, 1 and 150) makes the error go away. Am I missing something obvious? Is it not possible to assign 0 to a self-referencing Integer id column? Thanks! -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
[sqlalchemy] Re: Support for tuple expressions?
Thanks Michael. I won't be using or supporting SQL Server, so I'm quite fine with that. I guess the way forward would be to install SA in develop mode and make the changes directly? Excuse my ignorance, but why would you do it that way? Since I don't want to change any of the functionality of _Tuple I wouldn't think a subclass would be necessary. Also, since comparison are already captured by _CompareMixin and represented as _BinaryExpression, I would have thought that intercepting the compilation of _BinaryExpression in the sqlite dialect would be the way to go. --Buck On Apr 19, 6:51 am, Michael Bayer mike...@zzzcomputing.com wrote: there's a tuple_() operator: http://www.sqlalchemy.org/docs/core/expression_api.html?highlight=tup... the object returns is _Tuple. if you wanted fancy per-dialect expression behavior, mmm tricky, you'd need to subclass _Tuple (or write a new object), intercept comparisons like __eq__(), then return *another* construct that represents a Tuple Comparison, and that object would need per-dialect compilation rules. or you could lobby the sqlite folks to add support for the construct in the first place. though i doubt SQL Server has it either. On Apr 18, 2011, at 4:57 PM, bukzor wrote: SQL-92 defines a row value constructor expression like (1,2,3) which looks and behaves exactly like a Python tuple, as far as I can tell. These are implemented correctly in mysql at least, and I believe PostgreSQL and Oracle as well, although I don't have access to those systems. What would be the best way to deal with this type of value in SQLAlchemy? Should I create a RowValue class which can be visited by the various dialects? If I wanted to provide emulation for dialects which don't directly support this standard, what would be the way to go? For example, I'd like to be able to expand RowValue((1,2)) = RowValue(colA, colB) to 1 colA or (1=colA and 2 = ColB) under sqlite. --Buck -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group athttp://groups.google.com/group/sqlalchemy?hl=en. -- You received this message because you are subscribed to the Google Groups sqlalchemy group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.