Re: [sqlalchemy] Declarative, Imports and Base
On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote: Hi, I am having a small issue with multiple python modules and declarative... I might miss something but Consider: a.py: 8--- Base = declarative_base() class A(Base): ... 8--- b.py Base = declarative_base() class B(Base): ... 8--- c.py Base = declarative_base() class C(Base): ... 8--- d.py Base = declarative_base() from A import * # imports base from B import * # imports base from C import * # imports base Class D1(Base) ... Class D2(A) ... in d.py I want to create: def create_tables(engine): metadata= Base.metadata metadata.create_all(engine) Is there any way to properly add the metadata from the imported modules in d.py to the Base.metadata during the import..? Think of modules a,b,c and d are together in a package and d is imported with similar packages into something bigger Usually the convention is that all modules in an application share the same declarative base object (i.e. Base). If you wanted multiple Base objects but have them share a common MetaData, you can declare the MetaData up front, then create each Base using declarative_base(metadata=my_metadata). Otherwise if you're really looking to merge together multiple MetaData objects, that's not really in the API right now in a clean way, you'd perhaps call .tometadata() on each Table object but that's really not what I would do here - it copies the whole Table object and isn't really for a use case like this. If you can at least have a common MetaData object, or better a common Base object, that would be the best way to go. -- 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] Declarative, Imports and Base
Michael, Do you ever sleep? I am not sure I get your point. How do I set up a common Base. I could do Base= Declarative_base() from a import A (or * not sure how this differs in this case) from b import B (or *) If I do not declare Base in module a I get an Import Error on class A(Base), the same for importing b. This gets even more complicated when Base should be build from classes defined across modules. at the end there is one main.py importing all modules and this should be able to define the Main Base. Any suggestions on how to tackle this. I know have multiple modules and am glueing everything together. This even gets more problematic with Inheritance. one solution could be.. from a import A, BaseA from b import B, BaseB Base = declarative_base() metadata - BaseA.metadata + BaseB.metadata metadata.create_all(engine) What I do not get is how the mapper is configured. Normally with declarative Base it is not used in Production fase for as far as I can see. The mapper is part of the Class right? and session does not use Base at all? but gets it when needed - Session.query(A). ? Or am I totally wrong on this? Can I something like this: from a import * (imports class A and the declarative_base BaseA) Base = declarative_base() class C(Base): ... BaseForB = declarative_base(metadata=BaseA) class B(BaseForB) Mixin classes are of type object so there is no issue since @declared_attr etc works class D(Base,mixinclass) works without a Base at all so there is no Issue Am I right? in understanding your comments on my first mail in this topic? Martijn On Feb 8, 2011, at 7:46 PM, Michael Bayer wrote: On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote: Hi, I am having a small issue with multiple python modules and declarative... I might miss something but Consider: a.py: 8--- Base = declarative_base() class A(Base): ... 8--- b.py Base = declarative_base() class B(Base): ... 8--- c.py Base = declarative_base() class C(Base): ... 8--- d.py Base = declarative_base() from A import * # imports base from B import * # imports base from C import * # imports base Class D1(Base) ... Class D2(A) ... in d.py I want to create: def create_tables(engine): metadata= Base.metadata metadata.create_all(engine) Is there any way to properly add the metadata from the imported modules in d.py to the Base.metadata during the import..? Think of modules a,b,c and d are together in a package and d is imported with similar packages into something bigger Usually the convention is that all modules in an application share the same declarative base object (i.e. Base). If you wanted multiple Base objects but have them share a common MetaData, you can declare the MetaData up front, then create each Base using declarative_base(metadata=my_metadata). Otherwise if you're really looking to merge together multiple MetaData objects, that's not really in the API right now in a clean way, you'd perhaps call .tometadata() on each Table object but that's really not what I would do here - it copies the whole Table object and isn't really for a use case like this. If you can at least have a common MetaData object, or better a common Base object, that would be the best way to go. -- 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] Declarative, Imports and Base
Hi Martin, On 08/02/2011 19:25, Martijn Moeling wrote: I am not sure I get your point. How do I set up a common Base. I could do Base= Declarative_base() from a import A (or * not sure how this differs in this case) from b import B (or *) If I do not declare Base in module a I get an Import Error on class A(Base), the same for importing b. The answer is you define your base somewhere and have both a and b import it from there. This gets even more complicated when Base should be build from classes defined across modules. ...and then even more so when one base needs to be shared between multiple python packages ;-) Any suggestions on how to tackle this. I have a package I'm itching to release which will help with this. Keep your eyes open for 'mortar_rdb' ;-) (it's currently blocked on sqlalchemy-migrate getting a release and me doing some renaming from it's customer-specific internal name...) cheers, 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.
Re: [sqlalchemy] Declarative, Imports and Base
the idea is like this: myproject/ myproject/__init__.py myproject/meta.py myproject/somepackage/__init__.py myproject/somepackage/a.py myproject/someotherpackage/__init__.py myproject/someotherpackage/b.py myproject/__init__.py: from myproject.somepackage import a from myproject.someotherpackage import b meta.py: Base = declarative_base() a.py: from myproject.meta import Base b.py: from myproject.meta import Base On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote: Michael, Do you ever sleep? I am not sure I get your point. How do I set up a common Base. I could do Base= Declarative_base() from a import A (or * not sure how this differs in this case) from b import B (or *) If I do not declare Base in module a I get an Import Error on class A(Base), the same for importing b. This gets even more complicated when Base should be build from classes defined across modules. at the end there is one main.py importing all modules and this should be able to define the Main Base. Any suggestions on how to tackle this. I know have multiple modules and am glueing everything together. This even gets more problematic with Inheritance. one solution could be.. from a import A, BaseA from b import B, BaseB Base = declarative_base() metadata - BaseA.metadata + BaseB.metadata metadata.create_all(engine) What I do not get is how the mapper is configured. Normally with declarative Base it is not used in Production fase for as far as I can see. The mapper is part of the Class right? and session does not use Base at all? but gets it when needed - Session.query(A). ? Or am I totally wrong on this? Can I something like this: from a import * (imports class A and the declarative_base BaseA) Base = declarative_base() class C(Base): ... BaseForB = declarative_base(metadata=BaseA) class B(BaseForB) Mixin classes are of type object so there is no issue since @declared_attr etc works class D(Base,mixinclass) works without a Base at all so there is no Issue Am I right? in understanding your comments on my first mail in this topic? Martijn On Feb 8, 2011, at 7:46 PM, Michael Bayer wrote: On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote: Hi, I am having a small issue with multiple python modules and declarative... I might miss something but Consider: a.py: 8--- Base = declarative_base() class A(Base): ... 8--- b.py Base = declarative_base() class B(Base): ... 8--- c.py Base = declarative_base() class C(Base): ... 8--- d.py Base = declarative_base() from A import * # imports base from B import * # imports base from C import * # imports base Class D1(Base) ... Class D2(A) ... in d.py I want to create: def create_tables(engine): metadata= Base.metadata metadata.create_all(engine) Is there any way to properly add the metadata from the imported modules in d.py to the Base.metadata during the import..? Think of modules a,b,c and d are together in a package and d is imported with similar packages into something bigger Usually the convention is that all modules in an application share the same declarative base object (i.e. Base). If you wanted multiple Base objects but have them share a common MetaData, you can declare the MetaData up front, then create each Base using declarative_base(metadata=my_metadata). Otherwise if you're really looking to merge together multiple MetaData objects, that's not really in the API right now in a clean way, you'd perhaps call .tometadata() on each Table object but that's really not what I would do here - it copies the whole Table object and isn't really for a use case like this. If you can at least have a common MetaData object, or better a common Base object, that would be the best way to go. -- 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. -- 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
Re: [sqlalchemy] Declarative, Imports and Base
Clear, if all packages are in the same project that is.. and what if in a.py I want to inherit some class mapped with b.py mixin does not allways work as a solution subclassing (DeclarativeMeta) is an option, not sure Once I do a base=declarative_base(metadata=BaseB) every class x(Base) gets the Columns in BaseB to it ..? I have been setting up some tests and one way or the other I need to know how Session is using Base, if I can have multiple declarative_base instances and how Session relates to that. Consider this: Base = Declarative_base() class a(Base): def create_table(engine): b=a() metadata = b.metadata metadata.create_all(engine) Base = None # IMPORTANT IS Sessionmaker using intropsection to find out an instance of Declarative base? engine = Session = SessionMaker(bind=engine) would this or a similar approach work? On Feb 8, 2011, at 9:12 PM, Michael Bayer wrote: the idea is like this: myproject/ myproject/__init__.py myproject/meta.py myproject/somepackage/__init__.py myproject/somepackage/a.py myproject/someotherpackage/__init__.py myproject/someotherpackage/b.py myproject/__init__.py: from myproject.somepackage import a from myproject.someotherpackage import b meta.py: Base = declarative_base() a.py: from myproject.meta import Base b.py: from myproject.meta import Base On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote: Michael, Do you ever sleep? I am not sure I get your point. How do I set up a common Base. I could do Base= Declarative_base() from a import A (or * not sure how this differs in this case) from b import B (or *) If I do not declare Base in module a I get an Import Error on class A(Base), the same for importing b. This gets even more complicated when Base should be build from classes defined across modules. at the end there is one main.py importing all modules and this should be able to define the Main Base. Any suggestions on how to tackle this. I know have multiple modules and am glueing everything together. This even gets more problematic with Inheritance. one solution could be.. from a import A, BaseA from b import B, BaseB Base = declarative_base() metadata - BaseA.metadata + BaseB.metadata metadata.create_all(engine) What I do not get is how the mapper is configured. Normally with declarative Base it is not used in Production fase for as far as I can see. The mapper is part of the Class right? and session does not use Base at all? but gets it when needed - Session.query(A). ? Or am I totally wrong on this? Can I something like this: from a import * (imports class A and the declarative_base BaseA) Base = declarative_base() class C(Base): ... BaseForB = declarative_base(metadata=BaseA) class B(BaseForB) Mixin classes are of type object so there is no issue since @declared_attr etc works class D(Base,mixinclass) works without a Base at all so there is no Issue Am I right? in understanding your comments on my first mail in this topic? Martijn On Feb 8, 2011, at 7:46 PM, Michael Bayer wrote: On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote: Hi, I am having a small issue with multiple python modules and declarative... I might miss something but Consider: a.py: 8--- Base = declarative_base() class A(Base): ... 8--- b.py Base = declarative_base() class B(Base): ... 8--- c.py Base = declarative_base() class C(Base): ... 8--- d.py Base = declarative_base() from A import * # imports base from B import * # imports base from C import * # imports base Class D1(Base) ... Class D2(A) ... in d.py I want to create: def create_tables(engine): metadata= Base.metadata metadata.create_all(engine) Is there any way to properly add the metadata from the imported modules in d.py to the Base.metadata during the import..? Think of modules a,b,c and d are together in a package and d is imported with similar packages into something bigger Usually the convention is that all modules in an application share the same declarative base object (i.e. Base). If you wanted multiple Base objects but have them share a common MetaData, you can declare the MetaData up front, then create each Base using declarative_base(metadata=my_metadata). Otherwise if you're really looking to merge together multiple MetaData objects, that's not really in the API right now in a clean way, you'd perhaps call .tometadata() on each Table object but that's really not what I would do here - it copies the whole Table object and isn't really for a use case like this. If you can at
Re: [sqlalchemy] Declarative, Imports and Base
On Feb 8, 2011, at 3:57 PM, Martijn Moeling wrote: Clear, if all packages are in the same project that is.. and what if in a.py I want to inherit some class mapped with b.py mixin does not allways work as a solution subclassing (DeclarativeMeta) is an option, not sure Once I do a base=declarative_base(metadata=BaseB) every class x(Base) gets the Columns in BaseB to it ..? I have been setting up some tests and one way or the other I need to know how Session is using Base, if I can have multiple declarative_base instances and how Session relates to that. Consider this: Base = Declarative_base() class a(Base): def create_table(engine): b=a() metadata = b.metadata metadata.create_all(engine) Base = None # IMPORTANT IS Sessionmaker using intropsection to find out an instance of Declarative base? engine = Session = SessionMaker(bind=engine) would this or a similar approach work? Session does not care about Base, nor does MetaData. The Base gives you this: class MyObject(Base): ... related = relationship(Related) the string Related is looked up in a dictionary inside of Base. The dictionary is called _decl_class_registry. MetaData gives you this: class MyObject(Base): ... related_id = Column(Integer, ForeignKey('related.id')) the string 'related.id' is broken into 'related' and 'id' and is looked up inside a dictionary inside of MetaData(). The dictionary is called tables. There's some extra lookup helper mechanics surrounding this dictionary in 0.7 which is why we don't want you manipulating .tables directly. Those two registries are the *only* thing you get from a Base and a MetaData that is dependent on how many of them are in use. Neither is strictly needed. relationship() accepts the real class itself, i.e. relationship(Related). ForeignKey accepts a real column object, i.e. ForeignKey(related_table.c.id). The registries are strictly for the purpose of making it *easier* to organize table metadata and declarative classes without worrying about order of dependencies, allowing specification of related constructs via string name. Otherwise feel free to declare every single class and Table on its own Base and MetaData, it makes no difference. If you have multiple projects each with their own set of unrelated tables, there is no need to merge any Base or MetaData objects together. Simply call create_all() on each MetaData() object as needed. The namespaces remain entirely separate, as they should. If OTOH the multiple projects are linking to each other's tables and classes, then these projects have a dependency on each other. You should change them such that a common MetaData, and optionally a Base, can be specified from which they all make usage of - unless you can get away with not declaring any inter-package relationships or foreign keys with string names. On Feb 8, 2011, at 9:12 PM, Michael Bayer wrote: the idea is like this: myproject/ myproject/__init__.py myproject/meta.py myproject/somepackage/__init__.py myproject/somepackage/a.py myproject/someotherpackage/__init__.py myproject/someotherpackage/b.py myproject/__init__.py: from myproject.somepackage import a from myproject.someotherpackage import b meta.py: Base = declarative_base() a.py: from myproject.meta import Base b.py: from myproject.meta import Base On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote: Michael, Do you ever sleep? I am not sure I get your point. How do I set up a common Base. I could do Base= Declarative_base() from a import A (or * not sure how this differs in this case) from b import B (or *) If I do not declare Base in module a I get an Import Error on class A(Base), the same for importing b. This gets even more complicated when Base should be build from classes defined across modules. at the end there is one main.py importing all modules and this should be able to define the Main Base. Any suggestions on how to tackle this. I know have multiple modules and am glueing everything together. This even gets more problematic with Inheritance. one solution could be.. from a import A, BaseA from b import B, BaseB Base = declarative_base() metadata - BaseA.metadata + BaseB.metadata metadata.create_all(engine) What I do not get is how the mapper is configured. Normally with declarative Base it is not used in Production fase for as far as I can see. The mapper is part of the Class right? and session does not use Base at all? but gets it when needed - Session.query(A). ? Or am I totally wrong on this? Can I something like this: from a import * (imports class A and the declarative_base BaseA) Base = declarative_base() class C(Base): ... BaseForB = declarative_base(metadata=BaseA)
Re: [sqlalchemy] Declarative, Imports and Base
Clear! On Feb 8, 2011, at 10:21 PM, Michael Bayer wrote: On Feb 8, 2011, at 3:57 PM, Martijn Moeling wrote: Clear, if all packages are in the same project that is.. and what if in a.py I want to inherit some class mapped with b.py mixin does not allways work as a solution subclassing (DeclarativeMeta) is an option, not sure Once I do a base=declarative_base(metadata=BaseB) every class x(Base) gets the Columns in BaseB to it ..? I have been setting up some tests and one way or the other I need to know how Session is using Base, if I can have multiple declarative_base instances and how Session relates to that. Consider this: Base = Declarative_base() class a(Base): def create_table(engine): b=a() metadata = b.metadata metadata.create_all(engine) Base = None # IMPORTANT IS Sessionmaker using intropsection to find out an instance of Declarative base? engine = Session = SessionMaker(bind=engine) would this or a similar approach work? Session does not care about Base, nor does MetaData. The Base gives you this: class MyObject(Base): ... related = relationship(Related) the string Related is looked up in a dictionary inside of Base. The dictionary is called _decl_class_registry. MetaData gives you this: class MyObject(Base): ... related_id = Column(Integer, ForeignKey('related.id')) the string 'related.id' is broken into 'related' and 'id' and is looked up inside a dictionary inside of MetaData(). The dictionary is called tables.There's some extra lookup helper mechanics surrounding this dictionary in 0.7 which is why we don't want you manipulating .tables directly. Those two registries are the *only* thing you get from a Base and a MetaData that is dependent on how many of them are in use. Neither is strictly needed. relationship() accepts the real class itself, i.e. relationship(Related). ForeignKey accepts a real column object, i.e. ForeignKey(related_table.c.id).The registries are strictly for the purpose of making it *easier* to organize table metadata and declarative classes without worrying about order of dependencies, allowing specification of related constructs via string name. Otherwise feel free to declare every single class and Table on its own Base and MetaData, it makes no difference. If you have multiple projects each with their own set of unrelated tables, there is no need to merge any Base or MetaData objects together. Simply call create_all() on each MetaData() object as needed. The namespaces remain entirely separate, as they should. If OTOH the multiple projects are linking to each other's tables and classes, then these projects have a dependency on each other. You should change them such that a common MetaData, and optionally a Base, can be specified from which they all make usage of - unless you can get away with not declaring any inter-package relationships or foreign keys with string names. On Feb 8, 2011, at 9:12 PM, Michael Bayer wrote: the idea is like this: myproject/ myproject/__init__.py myproject/meta.py myproject/somepackage/__init__.py myproject/somepackage/a.py myproject/someotherpackage/__init__.py myproject/someotherpackage/b.py myproject/__init__.py: from myproject.somepackage import a from myproject.someotherpackage import b meta.py: Base = declarative_base() a.py: from myproject.meta import Base b.py: from myproject.meta import Base On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote: Michael, Do you ever sleep? I am not sure I get your point. How do I set up a common Base. I could do Base= Declarative_base() from a import A (or * not sure how this differs in this case) from b import B (or *) If I do not declare Base in module a I get an Import Error on class A(Base), the same for importing b. This gets even more complicated when Base should be build from classes defined across modules. at the end there is one main.py importing all modules and this should be able to define the Main Base. Any suggestions on how to tackle this. I know have multiple modules and am glueing everything together. This even gets more problematic with Inheritance. one solution could be.. from a import A, BaseA from b import B, BaseB Base = declarative_base() metadata - BaseA.metadata + BaseB.metadata metadata.create_all(engine) What I do not get is how the mapper is configured. Normally with declarative Base it is not used in Production fase for as far as I can see. The mapper is part of the Class right? and session does not use Base at all? but gets it when needed - Session.query(A). ? Or am I totally wrong on this? Can I something like this: from a import * (imports class A and the declarative_base BaseA)