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.

Reply via email to