[sqlalchemy] how to delete record (special case)
Hello, I am experimenting with a pattern where records hold the table name and record id of the next record in any other table, chaining records in different tables. This works, but I can't figure out how to clean op references to the next record in another table when I delete a record (the pattern does not use foreign keys in the normal sense). The code is: = from sqlalchemy import * from sqlalchemy.orm.session import sessionmaker from sqlalchemy.ext.declarative import declarative_base, declared_attr, DeclarativeMeta #--- Base = declarative_base() reg = dict() engine = create_engine('sqlite:///:memory:', echo=False) Session = sessionmaker(bind = engine) #--- class chainmeta(DeclarativeMeta): #--- class Base(object): session = Session() @declared_attr def __tablename__(cls): return cls.__name__ id = Column(Integer, primary_key = True) next_table = Column(String(64)) next_id = Column(Integer) #in table with name stored in next_table! def __init__(self, data, next = None): self.data = data self.prev = None self.next = next self.session.add(self) self.session.flush() def _getnext(self): if self.next_table and self.next_id: return self.session.query(reg[self.next_table]).filter(self.next_id == reg[self.next_table].id).one() else: return None def _setnext(self, next): if next: if self.next: self.next.prev = None self.next_table = next.__tablename__ self.next_id = next.id next.prev = self elif self.next: self.next.prev = None self.next_table = None self.next_id = None def _delnext(self): self.next.prev = None self.next_table = None self.next_id = None next = property(_getnext, _setnext, _delnext) def __repr__(self): out = type: + type(self).__name__ + [ for name in self.__dict__: out += name + , out += ] return out #--- def __new__(mcls, name, coltype): return DeclarativeMeta.__new__(mcls, name, (chainmeta.Base, Base),{data: Column(coltype, nullable = False)}) def __init__(cls, name, coltype): reg[name] = cls return DeclarativeMeta.__init__(cls, name, (chainmeta.Base, Base),{}) #--- if __name__ == '__main__': Base.metadata.drop_all(engine) session = chainmeta.Base.session = Session() Ni = chainmeta(Ni, Integer) Nb = chainmeta(Nb, Boolean) Nt = chainmeta(Nt, String(200)) Base.metadata.create_all(engine) ni1 = Ni(5) ni2 = Ni(12) nb1 = Nb(True) nb2 = Nb(False) nt1 = Nt(text in nt1) nt2 = Nt(text in nt2) ni1.next = ni2 ni2.next = nb1 nb1.next = nb2 nb2.next = nt1 nt1.next = nt2 nt2.next = ni1 #circular print OBJECTS n = ni1 count = 0 print nexts: . while n and count 10: print n.data count += 1 n = n.next n = ni1 count = 0 print prevs: . while n and count 10: print n.data count += 1 n = n.prev print --- nts = session.query(Nt).all() print QUERIES for nt in nts: print nt.data print + print session.query(Ni).filter(Ni.next_id == nb1.id).first().data = This might seem to have no reasonable us case, but it is something I want to use in a more complicated pattern later on. Basically the question is, how can I remove a record and have no next or prev pointing to it in other objects or records (without adding some sort of external controller)? Cheers, Lars -- 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: when is object.id initialized
Thank you, I now experiment with putting session.add and session.flush in object.__init__ .. Are there any general disadvantages of that approach? On Apr 3, 7:44 pm, Michael Bayer mike...@zzzcomputing.com wrote: Integer primary key identifiers are generated by the database itself using a variety of techniques which are all database-dependent. This process occurs when the session flushes. If you read the object relational tutorial starting athttp://www.sqlalchemy.org/docs/orm/tutorial.html#setting-up-the-mappingand working down through the end ofhttp://www.sqlalchemy.org/docs/orm/tutorial.html#adding-new-objectsyou will see that this interaction is described. You can of course set .id to any value you'd like and that will be the value used when the flush happens. On Apr 3, 2011, at 1:09 PM, farcat wrote: Hi all, I use a kind of dynamic reference from parent_table to other tables. For that parent_table uses columns table_name and a record_id. This makes it possible to have a reference from parent_table to any record in any table in the database. However, say that i want to reference a record of table_name, i need the record.id to initialize parent_table.record_id. However, when i create a record and session.add it to the database, record.id == None. I was wondering when and how record.id is initialized and how it can be forced. Cheers, Lars -- 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.
[sqlalchemy] Re: difficult error from Base.metadata.create_all(engine)
OK, after a long day of experimentation ... I found a solution. This is the new code (compare to old copied in above): -- class tablemeta(DeclarativeMeta): def __new__(mcls, typedef): return DeclarativeMeta.__new__(mcls, str(typedef.name), (BaseTable,Base), {}) def __init__(cls, typedef): reg[cls.__name__] = cls cls.links = linkmeta(typedef) DeclarativeMeta.__init__(cls, typedef.name, (BaseTable,Base), {}) #== FIRST members = typedef.all() cls.__setlinks(members) #== ADD RELATIONSHIPS def __setlinks(cls, members): for mem in members: setattr(cls, _ + mem.name, relationship(cls.links, uselist = (mem.multiplicity != one), backref = mem.name, primaryjoin = and_(cls.links.parent_id == cls.id, cls.links.member_name == mem.name))) - The problem seemed to be in the order of adding relationships. The main difference is that now i call DeclarativeMeta.__init__ before adding relationships. Even using a dict with relationship attributes as last argument to __init__ did not work.( BTW cls.links is a table/ class used for references to records in dynamic other tables.) Hope this helps someone in the future; the error messages can be very confusing. On Apr 2, 2:59 pm, farcat gemer...@gmail.com wrote: Hello, I get the following error: ___ Traceback (most recent call last): File D:\Documents\Code\Eclipse\workspace\SQLAtest\data.py, line 29, in module I1 = reg[integer](integer = 5321) File string, line 4, in __init__ File C:\python27\lib\site-packages\sqlalchemy\orm\state.py, line 100, in initialize_instance fn(self, instance, args, kwargs) File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 2413, in _event_on_init instrumenting_mapper.compile() File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 807, in compile mapper._post_configure_properties() File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 837, in _post_configure_properties prop.init() File C:\python27\lib\site-packages\sqlalchemy\orm\interfaces.py, line 475, in init self.do_init() File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 900, in do_init self._determine_synchronize_pairs() File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 1157, in _determine_synchronize_pairs eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 1141, in _sync_pairs_from_join self sqlalchemy.exc.ArgumentError: Could not determine relationship direction for primaryjoin condition 'False AND False', on relationship F_Address_links.number. Ensure that the referencing Column objects have a ForeignKey present, or are otherwise part of a ForeignKeyConstraint on their parent Table, or specify the foreign_keys parameter to this relationship. Strange thing is that the line I1 = reg[integer](integer = 5321) is the first object/record I create and it works when I do not create any other classes. Also the class/table F_Address_links in the error message exists but no objects/records have been created yet. For example I do not understand how I1 = reg[integer](integer = 5321) leads to a call to a method that does anything with F_Address_links or related class/table F_Address. Please help ... It might be related to the ForeignKey in the code I showed earlier in this thread, but I don't see how. On Apr 2, 11:56 am, farcat gemer...@gmail.com wrote: He Michael, You saved me again .. Thanks! On Apr 2, 2:09 am, Michael Bayer mike...@zzzcomputing.com wrote: On Apr 1, 2011, at 2:52 PM, farcat wrote: Hi Michael, Still stuck, I don't mixin foreign keys or relationships. When is a Column attached to a table in declarative? so you have a few things like: class AtomBase(BaseBase): id = Column(Integer, primary_key=True) where AtomBase does not appear to be a declarative class. Its hard to follow but it appears AtomBase is taking the path that mixins take in declarative (indeed: __new__(mcls, name, (AtomBase, Base)). This means id will be copied for each actual declarative class generated from AtomBase. Later you have: ForeignKey(parent.id), This is referencing an id column probably too early. In all likelihood It isn't being linked to a table, a copy of it is. Use ForeignKey(parent_table_name.id) instead so that the column is evaluated
[sqlalchemy] when is object.id initialized
Hi all, I use a kind of dynamic reference from parent_table to other tables. For that parent_table uses columns table_name and a record_id. This makes it possible to have a reference from parent_table to any record in any table in the database. However, say that i want to reference a record of table_name, i need the record.id to initialize parent_table.record_id. However, when i create a record and session.add it to the database, record.id == None. I was wondering when and how record.id is initialized and how it can be forced. Cheers, Lars -- 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: difficult error from Base.metadata.create_all(engine)
Hi Michael, Could cls.links.member_name == mem.name have been the problem? mem.name is just a string. cls and cls.links are classes/tables (links is just an extra attribute in cls). Regards, Lars Ce On Apr 3, 6:53 pm, Michael Bayer mike...@zzzcomputing.com wrote: On Apr 3, 2011, at 11:50 AM, farcat wrote: The problem seemed to be in the order of adding relationships. The main difference is that now i call DeclarativeMeta.__init__ before adding relationships. Even using a dict with relationship attributes as last argument to __init__ did not work.( BTW cls.links is a table/ class used for references to records in dynamic other tables.) The declarative metaclass itself receives relationship() objects and initializes them just fine when used normally. It appears like you were creating a relationship() passing in non-SQL expression objects (i.e. not Column objects or similar), so an expression like x==y would just be False. On Apr 2, 2:59 pm, farcat gemer...@gmail.com wrote: Hello, I get the following error: ___ Traceback (most recent call last): File D:\Documents\Code\Eclipse\workspace\SQLAtest\data.py, line 29, in module I1 = reg[integer](integer = 5321) File string, line 4, in __init__ File C:\python27\lib\site-packages\sqlalchemy\orm\state.py, line 100, in initialize_instance fn(self, instance, args, kwargs) File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 2413, in _event_on_init instrumenting_mapper.compile() File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 807, in compile mapper._post_configure_properties() File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 837, in _post_configure_properties prop.init() File C:\python27\lib\site-packages\sqlalchemy\orm\interfaces.py, line 475, in init self.do_init() File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 900, in do_init self._determine_synchronize_pairs() File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 1157, in _determine_synchronize_pairs eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 1141, in _sync_pairs_from_join self sqlalchemy.exc.ArgumentError: Could not determine relationship direction for primaryjoin condition 'False AND False', on relationship F_Address_links.number. Ensure that the referencing Column objects have a ForeignKey present, or are otherwise part of a ForeignKeyConstraint on their parent Table, or specify the foreign_keys parameter to this relationship. Strange thing is that the line I1 = reg[integer](integer = 5321) is the first object/record I create and it works when I do not create any other classes. Also the class/table F_Address_links in the error message exists but no objects/records have been created yet. For example I do not understand how I1 = reg[integer](integer = 5321) leads to a call to a method that does anything with F_Address_links or related class/table F_Address. Please help ... It might be related to the ForeignKey in the code I showed earlier in this thread, but I don't see how. On Apr 2, 11:56 am, farcat gemer...@gmail.com wrote: He Michael, You saved me again .. Thanks! On Apr 2, 2:09 am, Michael Bayer mike...@zzzcomputing.com wrote: On Apr 1, 2011, at 2:52 PM, farcat wrote: Hi Michael, Still stuck, I don't mixin foreign keys or relationships. When is a Column attached to a table in declarative? so you have a few things like: class AtomBase(BaseBase): id = Column(Integer, primary_key=True) where AtomBase does not appear to be a declarative class. Its hard to follow but it appears AtomBase is taking the path that mixins take in declarative (indeed: __new__(mcls, name, (AtomBase, Base)). This means id will be copied for each actual declarative class generated from AtomBase. Later you have: ForeignKey(parent.id), This is referencing an id column probably too early. In all likelihood It isn't being linked to a table, a copy of it is. Use ForeignKey(parent_table_name.id) instead so that the column is evaluated as late as possible. My code is: import datetime from datatypes import * from accessors import member_accessor, reference_accessor from sqlalchemy import * from sqlalchemy.orm import relationship from sqlalchemy.orm.session import sessionmaker from sqlalchemy.ext.declarative import declared_attr, DeclarativeMeta from sqlalchemy.types import Text, BigInteger, Float, Boolean, Date, Time #-- - engine = create_engine('sqlite:///:memory:', echo=False) Session = sessionmaker(bind=engine) register
[sqlalchemy] Re: difficult error from Base.metadata.create_all(engine)
He Michael, You saved me again .. Thanks! On Apr 2, 2:09 am, Michael Bayer mike...@zzzcomputing.com wrote: On Apr 1, 2011, at 2:52 PM, farcat wrote: Hi Michael, Still stuck, I don't mixin foreign keys or relationships. When is a Column attached to a table in declarative? so you have a few things like: class AtomBase(BaseBase): id = Column(Integer, primary_key=True) where AtomBase does not appear to be a declarative class. Its hard to follow but it appears AtomBase is taking the path that mixins take in declarative (indeed: __new__(mcls, name, (AtomBase, Base)). This means id will be copied for each actual declarative class generated from AtomBase. Later you have: ForeignKey(parent.id), This is referencing an id column probably too early. In all likelihood It isn't being linked to a table, a copy of it is. Use ForeignKey(parent_table_name.id) instead so that the column is evaluated as late as possible. My code is: import datetime from datatypes import * from accessors import member_accessor, reference_accessor from sqlalchemy import * from sqlalchemy.orm import relationship from sqlalchemy.orm.session import sessionmaker from sqlalchemy.ext.declarative import declared_attr, DeclarativeMeta from sqlalchemy.types import Text, BigInteger, Float, Boolean, Date, Time #-- - engine = create_engine('sqlite:///:memory:', echo=False) Session = sessionmaker(bind=engine) register = dict() #-- - class BaseBase(object): session = Session() @declared_attr def __tablename__(cls): return cls.__name__ def __init__(self, **kwargs): Base.__init__(self, **kwargs) self.session.add(self) print str(self) + added to session + str(self.session) def __repr__(self): out = type: + type(self).__name__ + { for name, mem in self.__dict__: out += name + : + str(mem) + , out += } return out # class AtomBase(BaseBase): id = Column(Integer, primary_key=True) atomic = True # class atommeta(DeclarativeMeta): def __new__(mcls, name, coltype): return DeclarativeMeta.__new__(mcls, name, (AtomBase, Base), {name:Column(coltype, nullable = False)}) def __init__(cls, name, coltype): register[name] = cls return DeclarativeMeta.__init__(cls, name, (AtomBase, Base), {}) #-- - class BaseLink(BaseBase): member_name = Column(String(64), primary_key = True) #Name of member of parent class member_table = Column(String(64), primary_key = True) #Name of table in which value of member resides member_id = Column(Integer, primary_key = True) #record is in member_table, with previous column enables polymorphism def _getitem(self): t = register[self.member_table] return self.session.query(t).filter(self.member_id == t.id).one() def _setitem(self, val): try: del self.item except AttributeError: pass self.member_table = val.__tablename__ self.member_id = val.id def _delitem(self): t = register[self.member_table] self.session.query(t).filter(t.id == self.member_id).delete() item = property(_getitem, _setitem, _delitem) #-- - class BaseTable(BaseBase): id = Column(Integer, primary_key = True) created_at = Column(DateTime, default=datetime.datetime.now()) atomic = False #-- - class linkmeta(DeclarativeMeta): def __new__(mcls, parent): return DeclarativeMeta.__new__(mcls, %s_links % parent.__name__, (BaseLink, Base), {parent_id: Column(Integer, ForeignKey(parent.id), primary_key=True)}) def __init__(cls, parent): return DeclarativeMeta.__init__(cls, %s_links % parent.__name__, (BaseLink, Base), {}) #-- - class tablemeta(DeclarativeMeta): def __new__(mcls, typedef): out = DeclarativeMeta.__new__(mcls, str(typedef.name), (BaseTable,Base), {}) out.links = linkmeta(out) #== Creates class/table enables links to other tables members = typedef.all() for mem in members: if not mem.type.name in register: tablemeta(mem.type) setattr(out, _ + mem.name, relationship(out.links, uselist
[sqlalchemy] Re: difficult error from Base.metadata.create_all(engine)
Hello, I get the following error: ___ Traceback (most recent call last): File D:\Documents\Code\Eclipse\workspace\SQLAtest\data.py, line 29, in module I1 = reg[integer](integer = 5321) File string, line 4, in __init__ File C:\python27\lib\site-packages\sqlalchemy\orm\state.py, line 100, in initialize_instance fn(self, instance, args, kwargs) File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 2413, in _event_on_init instrumenting_mapper.compile() File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 807, in compile mapper._post_configure_properties() File C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 837, in _post_configure_properties prop.init() File C:\python27\lib\site-packages\sqlalchemy\orm\interfaces.py, line 475, in init self.do_init() File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 900, in do_init self._determine_synchronize_pairs() File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 1157, in _determine_synchronize_pairs eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) File C:\python27\lib\site-packages\sqlalchemy\orm\properties.py, line 1141, in _sync_pairs_from_join self sqlalchemy.exc.ArgumentError: Could not determine relationship direction for primaryjoin condition 'False AND False', on relationship F_Address_links.number. Ensure that the referencing Column objects have a ForeignKey present, or are otherwise part of a ForeignKeyConstraint on their parent Table, or specify the foreign_keys parameter to this relationship. Strange thing is that the line I1 = reg[integer](integer = 5321) is the first object/record I create and it works when I do not create any other classes. Also the class/table F_Address_links in the error message exists but no objects/records have been created yet. For example I do not understand how I1 = reg[integer](integer = 5321) leads to a call to a method that does anything with F_Address_links or related class/table F_Address. Please help ... It might be related to the ForeignKey in the code I showed earlier in this thread, but I don't see how. On Apr 2, 11:56 am, farcat gemer...@gmail.com wrote: He Michael, You saved me again .. Thanks! On Apr 2, 2:09 am, Michael Bayer mike...@zzzcomputing.com wrote: On Apr 1, 2011, at 2:52 PM, farcat wrote: Hi Michael, Still stuck, I don't mixin foreign keys or relationships. When is a Column attached to a table in declarative? so you have a few things like: class AtomBase(BaseBase): id = Column(Integer, primary_key=True) where AtomBase does not appear to be a declarative class. Its hard to follow but it appears AtomBase is taking the path that mixins take in declarative (indeed: __new__(mcls, name, (AtomBase, Base)). This means id will be copied for each actual declarative class generated from AtomBase. Later you have: ForeignKey(parent.id), This is referencing an id column probably too early. In all likelihood It isn't being linked to a table, a copy of it is. Use ForeignKey(parent_table_name.id) instead so that the column is evaluated as late as possible. My code is: import datetime from datatypes import * from accessors import member_accessor, reference_accessor from sqlalchemy import * from sqlalchemy.orm import relationship from sqlalchemy.orm.session import sessionmaker from sqlalchemy.ext.declarative import declared_attr, DeclarativeMeta from sqlalchemy.types import Text, BigInteger, Float, Boolean, Date, Time #-- - engine = create_engine('sqlite:///:memory:', echo=False) Session = sessionmaker(bind=engine) register = dict() #-- - class BaseBase(object): session = Session() @declared_attr def __tablename__(cls): return cls.__name__ def __init__(self, **kwargs): Base.__init__(self, **kwargs) self.session.add(self) print str(self) + added to session + str(self.session) def __repr__(self): out = type: + type(self).__name__ + { for name, mem in self.__dict__: out += name + : + str(mem) + , out += } return out # class AtomBase(BaseBase): id = Column(Integer, primary_key=True) atomic = True # class atommeta(DeclarativeMeta): def __new__(mcls, name, coltype): return DeclarativeMeta.__new__(mcls, name, (AtomBase, Base), {name:Column(coltype, nullable = False)}) def __init__(cls, name, coltype): register[name
[sqlalchemy] Re: difficult error from Base.metadata.create_all(engine)
(boolean, Boolean) atommeta(date, Date) atommeta(time, Time) typedefs = session.query(Type).filter(Type.atomic == False).all() for typedef in typedefs: tablemeta(typedef) print --- for reg in register: print reg Base.metadata.create_all(engine) #== ERROR printdone Please help The typedefs variables describe classes and members, and are queried from normal tables On Mar 31, 5:33 pm, Michael Bayer mike...@zzzcomputing.com wrote: On Mar 31, 2011, at 11:29 AM, farcat wrote: Hi, I am getting the following error after creating a number of classes through metaclasses: File C:\python27\lib\site-packages\sqlalchemy\dialects\sqlite \base.py, line 280, in visit_foreign_key_constraint if local_table.schema != remote_table.schema: AttributeError: 'NoneType' object has no attribute 'schema' Before I paste in any code (would need quite a lot), can anyone point me in the right direction? There's a Column not attached to a Table somewhere. Like, if you are creating a copy of a column, giving that to a table, but then the original is what you put in ForeignKey. -- 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.
[sqlalchemy] difficult error from Base.metadata.create_all(engine)
Hi, I am getting the following error after creating a number of classes through metaclasses: Traceback (most recent call last): File D:\Documents\Code\Eclipse\workspace\SQLAtest\data.py, line 20, in module createClasses(engine, session) File D:\Documents\Code\Eclipse\workspace\SQLAtest\src \dataclasses.py, line 126, in createClasses Base.metadata.create_all(engine) File C:\python27\lib\site-packages\sqlalchemy\schema.py, line 2148, in create_all bind.create(self, checkfirst=checkfirst, tables=tables) File C:\python27\lib\site-packages\sqlalchemy\engine\base.py, line 1698, in create connection=connection, **kwargs) File C:\python27\lib\site-packages\sqlalchemy\engine\base.py, line 1740, in _run_visitor **kwargs).traverse_single(element) File C:\python27\lib\site-packages\sqlalchemy\sql\visitors.py, line 83, in traverse_single return meth(obj, **kw) File C:\python27\lib\site-packages\sqlalchemy\engine\ddl.py, line 42, in visit_metadata self.traverse_single(table, create_ok=True) File C:\python27\lib\site-packages\sqlalchemy\sql\visitors.py, line 83, in traverse_single return meth(obj, **kw) File C:\python27\lib\site-packages\sqlalchemy\engine\ddl.py, line 58, in visit_table self.connection.execute(schema.CreateTable(table)) File C:\python27\lib\site-packages\sqlalchemy\engine\base.py, line 1191, in execute params) File C:\python27\lib\site-packages\sqlalchemy\engine\base.py, line 1241, in _execute_ddl compiled_ddl=ddl.compile(dialect=self.dialect), File C:\python27\lib\site-packages\sqlalchemy\sql\expression.py, line 1413, in compile compiler.compile() File C:\python27\lib\site-packages\sqlalchemy\engine\base.py, line 702, in compile self.string = self.process(self.statement) File C:\python27\lib\site-packages\sqlalchemy\engine\base.py, line 715, in process return obj._compiler_dispatch(self, **kwargs) File C:\python27\lib\site-packages\sqlalchemy\sql\visitors.py, line 54, in _compiler_dispatch return getter(visitor)(self, **kw) File C:\python27\lib\site-packages\sqlalchemy\sql\compiler.py, line 1160, in visit_create_table const = self.create_table_constraints(table) File C:\python27\lib\site-packages\sqlalchemy\sql\compiler.py, line 1178, in create_table_constraints (self.process(constraint) for constraint in constraints File C:\python27\lib\site-packages\sqlalchemy\sql\compiler.py, line 1177, in genexpr return , \n\t.join(p for p in File C:\python27\lib\site-packages\sqlalchemy\sql\compiler.py, line 1184, in genexpr not getattr(constraint, 'use_alter', False) File C:\python27\lib\site-packages\sqlalchemy\engine\base.py, line 715, in process return obj._compiler_dispatch(self, **kwargs) File C:\python27\lib\site-packages\sqlalchemy\sql\visitors.py, line 54, in _compiler_dispatch return getter(visitor)(self, **kw) File C:\python27\lib\site-packages\sqlalchemy\dialects\sqlite \base.py, line 280, in visit_foreign_key_constraint if local_table.schema != remote_table.schema: AttributeError: 'NoneType' object has no attribute 'schema' Before I paste in any code (would need quite a lot), can anyone point me in the right direction? -- 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] stuck on IntegrityError
Hi all, I am stuck on an integrity error. The code worked before, but i cannot figure out what changed so it does not anymore. It is possibly a dumn oversight. The code is: from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from sqlalchemy.orm.session import sessionmaker Base = declarative_base() def trim(txt): txt.strip() return txt inheritance_table = Table('inheritance', Base.metadata, Column('sub_name', String(50), ForeignKey('Type.name'), primary_key=True), Column('super_name', String(50), ForeignKey('Type.name'), primary_key=True)) class Member(Base): __tablename__ = 'Member' name = Column(String(50), primary_key=True) multiplicity = Column(Enum(uni, list, set), nullable = False) reference = Column(Boolean, nullable = False) type_name = Column(String(50),ForeignKey('Type.name'), nullable = False) of_type_name = Column(String(50),ForeignKey('Type.name'), primary_key=True) def __init__(self, name, type, multiplicity = uni, reference = False): self.name = trim(name) self.type = type self.reference = reference self.multiplicity = multiplicity def __repr__(self): return Member(%r, %r, %r, %r, %r) % (self.name, self.of_type_name, self.type_name, self.multiplicity, self.reference) class Type(Base): __tablename__ = 'Type' name = Column(String(50), primary_key=True) abstract = Column(Boolean, nullable = False) atomic = Column(Boolean, nullable = False) subtypes = relationship('Type', secondary=inheritance_table, primaryjoin=inheritance_table.c.super_name==name, secondaryjoin= name == inheritance_table.c.sub_name, backref='supertypes') members = relationship('Member', primaryjoin=Member.of_type_name==name, backref='of_type') of_members = relationship(Member, primaryjoin = Member.type_name == name, backref= type) def isSubOf(self, tp): if self == tp: return True for typ in self.supertypes: if typ.isSubOf(tp): return True return False def addSub(self, tp): if tp.atomic: raise Exception(type + tp.name + cannot have supertype) if self.isSubOf(tp): raise Exception(adding subtype + tp + creates cyclic inheritance) for mem in tp.members: self.check(mem.name, mem.type) self.subtypes.append(tp) def getAll(self): out = set(self.members) for typ in self.supertypes: out.update(typ.getAll()) return out def getAny(self, name): temp = self.getAll() for mem in temp: if mem.name == name: return mem return None def hasAny(self, name): return self.getAny(name) != None def check(self, name, typ, reference): if self.atomic: raise Exception(atomic type + self.name + cannot be changed) if self.hasAny(name): raise Exception(member name + name + already exists in this type or supertype) elif typ.isSubOf(self) and not reference: raise Exception(member type + type.name + equals this type or subtype) def add(self, name, type, multiplicity = one, reference = False): self.check(name, type, reference) self.members.append(Member(name, type, multiplicity, reference)) def __init__(self, name, atomic = False, abstract = False): self.name = name self.atomic = atomic self.abstract = abstract def __repr__(self): out = Type(%r): { % (self.name) for mem in self.members: out += str(mem) + , out += } return out if __name__ == __main__: engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.drop_all(engine) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() try: c1 = Type(A) c2 = Type(B) c1.add(m11, c2) session.add(c1) session.add(c2) session.commit() #== ERROR except Exception, e: print error: + str(e) raise and the error: Traceback (most recent call last): File D:\Documents\Code\Eclipse\workspace\test2\src\metadata.py, line 119, in module session.commit() File C:\python27\lib\site-packages\sqlalchemy\orm\session.py, line 614, in commit self.transaction.commit() File C:\python27\lib\site-packages\sqlalchemy\orm\session.py, line 385, in commit self._prepare_impl() File C:\python27\lib\site-packages\sqlalchemy\orm\session.py, line 369, in _prepare_impl self.session.flush() File
[sqlalchemy] Re: stuck on IntegrityError
I don't know whether to laugh or cry ... thanks On Mar 28, 6:25 pm, Michael Bayer mike...@zzzcomputing.com wrote: your enum is set for uni, list, set and you're passing in one On Mar 28, 2011, at 6:35 AM, farcat wrote: Hi all, I am stuck on an integrity error. The code worked before, but i cannot figure out what changed so it does not anymore. It is possibly a dumn oversight. The code is: from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from sqlalchemy.orm.session import sessionmaker Base = declarative_base() def trim(txt): txt.strip() return txt inheritance_table = Table('inheritance', Base.metadata, Column('sub_name', String(50), ForeignKey('Type.name'), primary_key=True), Column('super_name', String(50), ForeignKey('Type.name'), primary_key=True)) class Member(Base): __tablename__ = 'Member' name = Column(String(50), primary_key=True) multiplicity = Column(Enum(uni, list, set), nullable = False) reference = Column(Boolean, nullable = False) type_name = Column(String(50),ForeignKey('Type.name'), nullable = False) of_type_name = Column(String(50),ForeignKey('Type.name'), primary_key=True) def __init__(self, name, type, multiplicity = uni, reference = False): self.name = trim(name) self.type = type self.reference = reference self.multiplicity = multiplicity def __repr__(self): return Member(%r, %r, %r, %r, %r) % (self.name, self.of_type_name, self.type_name, self.multiplicity, self.reference) class Type(Base): __tablename__ = 'Type' name = Column(String(50), primary_key=True) abstract = Column(Boolean, nullable = False) atomic = Column(Boolean, nullable = False) subtypes = relationship('Type', secondary=inheritance_table, primaryjoin=inheritance_table.c.super_name==name, secondaryjoin= name == inheritance_table.c.sub_name, backref='supertypes') members = relationship('Member', primaryjoin=Member.of_type_name==name, backref='of_type') of_members = relationship(Member, primaryjoin = Member.type_name == name, backref= type) def isSubOf(self, tp): if self == tp: return True for typ in self.supertypes: if typ.isSubOf(tp): return True return False def addSub(self, tp): if tp.atomic: raise Exception(type + tp.name + cannot have supertype) if self.isSubOf(tp): raise Exception(adding subtype + tp + creates cyclic inheritance) for mem in tp.members: self.check(mem.name, mem.type) self.subtypes.append(tp) def getAll(self): out = set(self.members) for typ in self.supertypes: out.update(typ.getAll()) return out def getAny(self, name): temp = self.getAll() for mem in temp: if mem.name == name: return mem return None def hasAny(self, name): return self.getAny(name) != None def check(self, name, typ, reference): if self.atomic: raise Exception(atomic type + self.name + cannot be changed) if self.hasAny(name): raise Exception(member name + name + already exists in this type or supertype) elif typ.isSubOf(self) and not reference: raise Exception(member type + type.name + equals this type or subtype) def add(self, name, type, multiplicity = one, reference = False): self.check(name, type, reference) self.members.append(Member(name, type, multiplicity, reference)) def __init__(self, name, atomic = False, abstract = False): self.name = name self.atomic = atomic self.abstract = abstract def __repr__(self): out = Type(%r): { % (self.name) for mem in self.members: out += str(mem) + , out += } return out if __name__ == __main__: engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.drop_all(engine) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() try: c1 = Type(A) c2 = Type(B) c1.add(m11, c2) session.add(c1) session.add(c2) session.commit() #== ERROR except Exception, e: print error: + str(e) raise and the error: Traceback (most recent call last): File D:\Documents\Code\Eclipse\workspace\test2\src\metadata.py, line 119, in module
[sqlalchemy] Re: trouble with metaclass
Hi Chris, The short answer is that I want to dynamically create classes/tables and I want to implement multiple inheritance (simplified version: just data and no overrides = no diamond problem), so I need some extra work like a extra tables for polymorphism. I think it would be most elegant to do this with metaclasses, but I am just experimenting until now. I will look at the mixin classes chapter though; I have some more challenges ... The long answer (when i get it to work) might come later. Cheers, Lars On Mar 20, 8:33 pm, Chris Withers ch...@simplistix.co.uk wrote: On 19/03/2011 10:27, farcat wrote: OK, dumb error, move Base.metadata.create_all(engine) below table1 = tablemeta(table1) and it works. This works when I create the columns via the temp dict in __new__ not when I do so in __init__ (it complains about missing __tabledata__), but why? I'd strongly suggest reading the section on Mixin classes rather than doing stuff with Metaclasses: http://www.sqlalchemy.org/docs/orm/extensions/declarative.html?highli... If you *still* feel you need to use metaclasses after that, please let us know why! ;-) Chris -- Simplistix - Content Management, Batch Processing Python Consulting -http://www.simplistix.co.uk -- 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: trouble with metaclass
Well, (I am not a exactly a beginner in Python, just a bit rusty i guess :-) ) I am working on a way to persist multiple inheritance and polymorphism in a database, but I am a beginner with SQLalchemy. Anyway I have a new problem for which i would like some help: The following code gives an error: class tablemeta(DeclarativeMeta): def __new__(cls, name): temp = dict() temp[__tablename__] = _ + name temp[id] = Column(Integer, primary_key = True) temp[text] = Column(String(120)) return DeclarativeMeta.__new__(cls, name, (Base,), temp) def __init__(cls, name): return DeclarativeMeta.__init__(cls, name, (Base,),{}) if __name__ == __main__: engine = create_engine('sqlite:///tempDB.db', echo=True) Base.metadata.drop_all(engine) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() table1 = tablemeta(table1) row1 = table1(text = detextenzo) row2 = table1(text = detextenzoennogeenbeetje) session.add(row1) session.add(row2) session.commit() list = session.query(table1).all() #== ERROR for l in list: print str(l) File C:\Python27\lib\site-packages\sqlalchemy\engine\default.py, line 299, in do_execute cursor.execute(statement, parameters) sqlalchemy.exc.OperationalError: (OperationalError) no such table: _table1 u'INSERT INTO _table1 (text) VALUES (?)' ('detextenzo',) Seems an odd error, any ideas? On Mar 17, 6:20 pm, Chris Withers ch...@simplistix.co.uk wrote: On 16/03/2011 21:01, farcat wrote: I have an error i cant figure out (likely a beginners error): Beginners should not be using metaclasses. What's your use case here? Chris -- Simplistix - Content Management, Batch Processing Python Consulting -http://www.simplistix.co.uk -- 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] trouble with metaclass
I have an error i cant figure out (likely a beginners error): # Base = declarative_base() class tablemeta(DeclarativeMeta): def __new__(mcls, name): return DeclarativeMeta.__new__(mcls, name, (Base,), {}) def _init__(cls, name): temp = dict() temp[__tablename__] = _ + name temp[id] = Column(Integer, primary_key = True) temp[text] = Column(String(120)) DeclarativeMeta.__init__(cls, name, (Base,), temp) if __name__ == __main__: engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.drop_all(engine) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() table1 = tablemeta(table1) #= ERROR row1 = table1(text = detextenzo) row2 = table1(text = detextenzoennogeenbeetje) session.commit() list = session.query(table1).all() for l in list: print str(l) print done # the error is: # Traceback (most recent call last): File D:\Documents\Code\NetBeans\test\temp\src\temp.py, line 33, in module table1 = tablemeta(table1) TypeError: __init__() takes exactly 4 arguments (2 given) # I do not understand what __init__ i am miscalling: I call tablemeta.__init__ with 2 (1 implicit) as defined and DeclarativeMeta.__init__ with 4 as defined? please help ... -- 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: overriding DeclarativeBase and descriptors
thanks, I will start experimenting ... On Mar 5, 4:52 pm, Michael Bayer mike...@zzzcomputing.com wrote: On Mar 5, 2011, at 10:43 AM, farcat wrote: Hi, I am trying to implement polymorphism and multiple inheritance by: - adding a column to the parent class/table indicating the table from which the (polymorphic) class attribute object can be queried - adding the attribute name and the parent id to the child table/class to be able to find the attribute object in this table Now i want to use a descriptor and/or override __getattr__/__setattr__/ __getattribute__ to insert or get the correct (polymorphic) object from the correct table. What I was wondering was e.g. whether using a descriptor will inhibit SA from functioning correctly. Any tips to implement what i am trying to do would be very welcome. SQLAlchemy uses descriptors for all the mapped attributes and has several avenues to augmenting them with your own descriptors. __getattribute__ and __setattr__ work as expected, as does __getattr__ although that only applies to names that otherwise don't exist on the object. We encourage an extremely simple approach to descriptor access which is to name the columns in one way, and the descriptor in another. The synonym construct does this as does the newer hybrid attribute approach. Set and delete events can also be intercepted using the events module (new in 0.7 - in 0.6 use AttributeExtension). Cheers, Lars -- 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.
[sqlalchemy] overriding DeclarativeBase and descriptors
Hi, I am trying to implement polymorphism and multiple inheritance by: - adding a column to the parent class/table indicating the table from which the (polymorphic) class attribute object can be queried - adding the attribute name and the parent id to the child table/class to be able to find the attribute object in this table Now i want to use a descriptor and/or override __getattr__/__setattr__/ __getattribute__ to insert or get the correct (polymorphic) object from the correct table. What I was wondering was e.g. whether using a descriptor will inhibit SA from functioning correctly. Any tips to implement what i am trying to do would be very welcome. Cheers, Lars -- 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] multiple inheritance simplified case
Hi, I have been reading the posts on implementing multiple inheritance in SA. I have a question, for a slightly simpler method of MI, where there is no overriding of attributes (and e.g. therefore no diamond problem). This would mean that all underlying tables for classes could contain columns for all attributes (including the inherited ones, although these would also be attributes in the subclass). Hmm, ok, example in code: from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relation, sessionmaker Base = declarative_base() class report(Base): __tablename__ = reports name = Column(String(50), primary_key=True) text = Column(String(1000), nullable = False) def __init__(self, name, text): self.name = name self.text = text def __repr__(self): return report: + self.name + : + self.text class approvable(Base): __tablename__ = approvals id = Column(Integer, primary_key=True) approval = Column(Boolean) def __repr__(self): return approved: + self.approval class approvable_report(approvable, report): __tablename__ = approvable_reports def __init__(self, name, text, appr): self.name = name self.text = text self.approval = appr def __repr__(self): return report.__repr__(self) + approvable.__repr__(self) engine = create_engine('sqlite:///:memory:', echo=False) Base.metadata.create_all(engine) if __name__ == __main__: Session = sessionmaker(bind=engine) session = Session() ar = approvable_report(repje, this is the text of the report, True) session.add(ar) session.commit() ar2 = session.query(approvable_report).first() print ar2 It would be fine if the approvable_reports table had all columns of the superclasses (no overriding == no diamond problem), needing no foreign keys (or am i missing something), as long as the multiple inheritance relation in the python classes was maintained. I get the error: Traceback (most recent call last): File D:\Documents\Code\NetBeans\test\alchemy_test\src\alchemy.py, line 31, in module class approvable_report(approvable, report): File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py, line 1167, in __init__ _as_declarative(cls, classname, cls.__dict__) File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py, line 1099, in _as_declarative ignore_nonexistent_tables=True) File C:\Python27\lib\site-packages\sqlalchemy\sql\util.py, line 260, in join_condition between '%s' and '%s'.%s % (a.description, b.description, hint)) sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships between 'approvals' and 'approvable_reports'. Is there any way to get this to work? I don't see the need for a foreign key relationship between sub and superclasses in this case. -- 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: adjacency via table
thought i'd post the code I came up with for reference: from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.ext.associationproxy import association_proxy Base = declarative_base() def _create_inheritance(supertype, subtype): return Inheritance(supertype, subtype) inheritance_table = Table('inheritance', Base.metadata, Column('sub_name', String(50), ForeignKey('types.name'), primary_key=True), Column('super_name', String(50), ForeignKey('types.name'), primary_key=True)) class Type(Base): __tablename__ = 'types' name = Column(String(50), primary_key=True) abstract = Column(Boolean) top = Column(Boolean) subtypes = relationship('Type', secondary=inheritance_table, primaryjoin=inheritance_table.c.super_name==name, secondaryjoin=inheritance_table.c.sub_name==name, backref='supertypes') def hasSuper(self): return self.supertypes.length 0 def hasSub(self): return self.subtypes.length 0 def isAnySubOf(self, tp): #to check for cyclic inheritance if self == tp: return True for typ in self.supertypes: if typ.isAnySubOf(tp): return True return False def isAnySuperOf(self, tp): return tp.isAnySubOf(self) def addSub(self, tp): #some types cannot have supertypes: if not tp.top: #to check for cyclic inheritance: if not self.isAnySubOf(tp): self.subtypes.append(tp) else: raise Exception(cyclic inheritance) else: raise Exception(str(tp) + cannot have supertype) def addSuper(self, tp): tp.addSub(self) def __init__(self, name, top = False, abstract = False): self.name = name self.top = top self.abstract = abstract def __repr__(self): return Type(%r) % (self.name) engine = create_engine('sqlite:///:memory:', echo=False) Base.metadata.create_all(engine) if __name__ == __main__: Session = sessionmaker(bind=engine) session = Session() try: c1 = Type(A) c2 = Type(B) c3 = Type(C) c1.addSub(c2) c3.addSuper(c1) c3.addSuper(c2) c3.addSub(c1) #= would be cyclic print c1.subs for c in c1.subtypes: print + str(c) print c1.supers for c in c1.supertypes: print +str(c) print c2.subs for c in c2.subtypes: print + str(c) print c2.supers for c in c2.supertypes: print + str(c) print c3.subs for c in c3.subtypes: print + str(c) print c3.supers for c in c3.supertypes: print + str(c) except Exception, e: print error: + str(e) -- 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: adjacency via table
Thank you, Basically the multiple inheritance structure is a directional non- cyclic graph (i looked at the graph example code in the distribution, it uses methods to get next/previous nodes) . Members are basically another name for attributes. I understand the need for the primaryjoin now. However the many to many adjacency combination (graph) keeps eluding me. I would like to use the association class so i can use what i learned for the members class (types have multiple members, members have one type). Some more questions: 1) Is associationproxy the only way to create an attribute that skips the inheritance table, where do I indicate the primaryjoin then? 2) I am getting very confused: -- 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: adjacency via table
Thank you, Basically the multiple inheritance structure is a directional non- cyclic graph (i looked at the graph example code in the distribution, it uses methods to get next/previous nodes, which could serve as a workaround, but seems inelegant) . Members are basically another name for attributes. I understand the need for the primaryjoin now. However the many to many adjacency combination (graph) keeps eluding me. I would like to use the association class so i can use what i learned for the members class (types have multiple members, members have one type). Some more questions: 1) Is associationproxy the only way to create an attribute that skips the inheritance table, where do I indicate the primaryjoin then? 2) Is the point of a relationship() to make items in one class/table accessible through an attribute in another class? 3) I am confused about the error I am getting in: Base = declarative_base() def _create_inheritance(supertype, subtype): return Inheritance(supertype, subtype) class Inheritance(Base): __tablename__ = 'Inheritance' sub_name = Column(String(50), ForeignKey('Types.name'), primary_key=True) super_name = Column(String(50), ForeignKey('Types.name'), primary_key=True) def __init__(self, supertype, subtype): self.supertype = supertype self.subtype = subtype class Types(Base): __tablename__ = 'Types' name = Column(String(50), primary_key=True) abstract = Column(Boolean) subtypes = association_proxy('Inheritance', 'subtypes', creator =_create_inheritance) supertypes = association_proxy('Inheritance', 'supertypes', creator = _create_inheritance) def __init__(self, name, abstract = False): self.name = name self.abstract = abstract def __repr__(self): return Type(%r) % (self.name) engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.create_all(engine) if __name__ == __main__: Session = sessionmaker(bind=engine) session = Session() c1 = Types(A) c2 = Types(B) c3 = Types(C) c1.subtypes.append(c2) #=ERROR c3.supertypes.append(c1) With the Error: Traceback (most recent call last): File D:\Documents\Code\NetBeans\test\Alchemy\src\alchemy.py, line 63, in module c1.subtypes.append(c2) File C:\Python27\lib\site-packages\sqlalchemy\ext \associationproxy.py, line 164, in __get__ self.scalar = self._target_is_scalar() File C:\Python27\lib\site-packages\sqlalchemy\ext \associationproxy.py, line 156, in _target_is_scalar return not self._get_property().uselist File C:\Python27\lib\site-packages\sqlalchemy\ext \associationproxy.py, line 148, in _get_property 2011-02-20 16:12:12,595 INFO sqlalchemy.engine.base.Engine.0x...ef0L COMMIT get_property(self.target_collection)) File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 933, in get_property (self, key)) sqlalchemy.exc.InvalidRequestError: Mapper 'Mapper|Types|Types' has no property 'Inheritance' What does this mean? Actually I am getting confused in general about how to implement the combination of many to many relationships on the same table. Please help. -- 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: adjacency via table
Thank you, the many to many (following the pattern in the link above) seems to work, now on to the association table (later ... ) Cheers BTW: in A - (one to many) B - C, does (seen from A) primaryjoin refer to the relation between A and B and secondaryjoin to the relation between B and C? Otherwise that might explain some of my difficulties. -- 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] adjacency via table
Hi, I am trying to implement tables to store a basic multiple inheritance scheme via SA. I am pretty new to SA and could use some help with the following code: code from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy.ext.associationproxy import association_proxy Base = declarative_base() def _create_inheritance(supertype, subtype): return Inheritance(supertype, subtype) class Inheritance(Base): __tablename__ = 'Inheritance' sub_name = Column(String(50), ForeignKey('Types.name'), primary_key=True) super_name = Column(String(50), ForeignKey('Types.name'), primary_key=True) def __init__(self, supertype, subtype): self.supertype = supertype self.subtype = subtype class Types(Base): __tablename__ = 'Types' name = Column(String(50), primary_key=True) abstract = Column(Boolean) subtypes = association_proxy('Inheritance', 'subtypes', creator = _create_inheritance) supertypes = association_proxy('Inheritance', 'supertypes', creator = _create_inheritance) def __init__(self, name, abstract = False): self.name = name self.abstract = abstract def __repr__(self): return Type(%r) % (self.name) class Members(Base): __tablename__ = 'Members' name = Column(String(50), primary_key=True) type_name = Column(String(50),ForeignKey('Types.name')) type = relationship(Types, backref= of_members, uselist=False) of_type_name = Column(String(50),ForeignKey('Types.name'), primary_key=True) of_type = relationship(Types, backref='members') def __init__(self, name, tp): self.name = name self.type = tp def __repr__(self): return Member(%r, %r) % (self.name, type.name) engine = create_engine('sqlite:///:memory:', echo=False) Base.metadata.create_all(engine) if __name__ == __main__: Session = sessionmaker(bind=engine) session = Session() c1 = Types(A) #= error below c2 = Types(B) c3 = Types(C) c1.members.append(Members(m1, c2)) /code I have the following 2 questions: 1) did i get the relationship between Types and Inheritance right? I want to be able to call supertypes and subtypes from any type directly. 2) loose question: how does sqlalchemy handle type errors, e.g. when i have an A.attr = Column(String), a = A(), a.attr = 15? (i use sqlite now, which accepts putting string in integer columns, but later i will use another DB ) 3) I get an error for the above code related to the Members class which i don't understand, can anyone explain/help with a fix: Traceback (most recent call last): File D:\Documents\Code\NetBeans\test\Alchemy\src\alchemy.py, line 60, in module c1 = Types(A) File string, line 4, in __init__ File C:\Python27\lib\site-packages\sqlalchemy\orm\state.py, line 100, in initialize_instance fn(self, instance, args, kwargs) File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 2413, in _event_on_init instrumenting_mapper.compile() File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 807, in compile mapper._post_configure_properties() File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line 837, in _post_configure_properties prop.init() File C:\Python27\lib\site-packages\sqlalchemy\orm\interfaces.py, line 475, in init self.do_init() File C:\Python27\lib\site-packages\sqlalchemy\orm\properties.py, line 899, in do_init self._determine_joins() File C:\Python27\lib\site-packages\sqlalchemy\orm\properties.py, line 1028, in _determine_joins % self) sqlalchemy.exc.ArgumentError: Could not determine join condition between parent/child tables on relationship Members.type. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well. Any help and clarifications are welcome! -- 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] dynamic classes and tables
Hi everyone, I am new to sqlalchemy and figuring out whether it is right for my project. What I am looking for is the ability to change classes and tables on the flight, with as much freedom as possible, potentially having metaclasses figuring out the difference between versions and updating the database accordingly. Additionally I would like to import databases and automatically generate class definitions. Some code I tried: code from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relation, sessionmaker Base = declarative_base() def Init(self, title=None, year=None): self.title = title self.year = year def Repr(self): return Movie(%r, %r, %r) % (self.title, self.year, self.director) Movie = type(Movie, (Base,),{'__tablename__': movies, id:Column(Integer, primary_key=True), title: Column(String(255), nullable=False), year: Column(Integer), directed_by: Column(Integer, ForeignKey('directors.id')), director: relation(Director, backref='movies', lazy=False)}) setattr(Movie, __init__, classmethod(Init)) setattr(Movie, __repr__, classmethod(Repr)) class Director(Base): __tablename__ = 'directors' id = Column(Integer, primary_key=True) name = Column(String(50), nullable=False, unique=True) def __init__(self, name=None): self.name = name def __repr__(self): return Director(%r) % (self.name) engine = create_engine('sqlite:///meta.db', echo=True) Base.metadata.create_all(engine) if __name__ == __main__: Session = sessionmaker(bind=engine) session = Session() m1 = Movie(Star Trek, 2009) m1.director = Director(JJ Abrams) d2 = Director(George Lucas) d2.movies = [Movie(Star Wars, 1977), Movie(THX 1138, 1971)] try: session.add(m1) session.add(d2) session.commit() except: session.rollback() alldata = session.query(Movie).all() for somedata in alldata: print somedata \code with as error: 2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L PRAGMA table_info(directors) 2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L () Traceback (most recent call last): File D:\Documents\Code\NetBeans\test\alchemy\src\alchemy.py, line 49, in module m1.director = Director(JJ Abrams) File C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py, line 158, in __set__ 2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L PRAGMA table_info(movies) 2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L () self.impl.set(instance_state(instance), AttributeError: 'Movie' object has no attribute '_sa_instance_state' Can anyone shed some light or explain the error message? -- 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: dynamic classes and tables
Thank you, that works. Is there any way to later add or remove attributes, using the declarative system? Cheers, Lars On Feb 8, 10:46 pm, Michael Bayer mike...@zzzcomputing.com wrote: On Feb 8, 2011, at 3:52 PM, farcat wrote: Hi everyone, I am new to sqlalchemy and figuring out whether it is right for my project. What I am looking for is the ability to change classes and tables on the flight, with as much freedom as possible, potentially having metaclasses figuring out the difference between versions and updating the database accordingly. Additionally I would like to import databases and automatically generate class definitions. Some code I tried: code from sqlalchemy import * from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relation, sessionmaker Base = declarative_base() def Init(self, title=None, year=None): self.title = title self.year = year def Repr(self): return Movie(%r, %r, %r) % (self.title, self.year, self.director) Movie = type(Movie, (Base,),{'__tablename__': movies, id:Column(Integer, primary_key=True), title: Column(String(255), nullable=False), year: Column(Integer), directed_by: Column(Integer, ForeignKey('directors.id')), director: relation(Director, backref='movies', lazy=False)}) setattr(Movie, __init__, classmethod(Init)) setattr(Movie, __repr__, classmethod(Repr)) class Director(Base): __tablename__ = 'directors' id = Column(Integer, primary_key=True) name = Column(String(50), nullable=False, unique=True) def __init__(self, name=None): self.name = name def __repr__(self): return Director(%r) % (self.name) engine = create_engine('sqlite:///meta.db', echo=True) Base.metadata.create_all(engine) if __name__ == __main__: Session = sessionmaker(bind=engine) session = Session() m1 = Movie(Star Trek, 2009) m1.director = Director(JJ Abrams) d2 = Director(George Lucas) d2.movies = [Movie(Star Wars, 1977), Movie(THX 1138, 1971)] try: session.add(m1) session.add(d2) session.commit() except: session.rollback() alldata = session.query(Movie).all() for somedata in alldata: print somedata \code with as error: 2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L PRAGMA table_info(directors) 2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L () Traceback (most recent call last): File D:\Documents\Code\NetBeans\test\alchemy\src\alchemy.py, line 49, in module m1.director = Director(JJ Abrams) File C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py, line 158, in __set__ 2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L PRAGMA table_info(movies) 2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L () self.impl.set(instance_state(instance), AttributeError: 'Movie' object has no attribute '_sa_instance_state' Can anyone shed some light or explain the error message? your __init__ monkeypatch is interfering with SQLA's wrapping of this method. Try Movie = type(Movie, (Base,),{'__tablename__': movies, __init__:Init, id:Column(Integer, primary_key=True), title: Column(String(255), nullable=False), year: Column(Integer), directed_by: Column(Integer,ForeignKey('directors.id')), director: relation(Director, backref='movies',lazy=False)}) instead. -- 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.