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) >>>> >>>> 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 >>> 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 > 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.