root / elixir / trunk / elixir / __init__.py @ 267

Revision 267, 4.4 kB (checked in by ged, 7 years ago)
  • cleanup class attributes (in the attributes-based syntax) after the
    property is attached to its entity, so that SQLAlchemy is not confused.
    Only caused problem in the case of single inheritance and when omitting
    some values. See SA ticket #866.
  • some PEP8 fixes
Line 
1'''
2Elixir package
3
4A declarative layer on top of the `SQLAlchemy library
5<http://www.sqlalchemy.org/>`_. It is a fairly thin wrapper, which provides
6the ability to create simple Python classes that map directly to relational
7database tables (this pattern is often referred to as the Active Record design
8pattern), providing many of the benefits of traditional databases
9without losing the convenience of Python objects.
10
11Elixir is intended to replace the ActiveMapper SQLAlchemy extension, and the
12TurboEntity project but does not intend to replace SQLAlchemy's core features,
13and instead focuses on providing a simpler syntax for defining model objects
14when you do not need the full expressiveness of SQLAlchemy's manual mapper
15definitions.
16'''
17
18try:
19    set
20except NameError:
21    from sets import Set as set
22
23import sqlalchemy
24from sqlalchemy.types import *
25
26from elixir.options import using_options, using_table_options, \
27                           using_mapper_options, options_defaults
28from elixir.entity import Entity, EntityMeta, EntityDescriptor, \
29                          setup_entities, cleanup_entities
30from elixir.fields import has_field, with_fields, Field
31from elixir.relationships import belongs_to, has_one, has_many, \
32                                 has_and_belongs_to_many, \
33                                 ManyToOne, OneToOne, OneToMany, ManyToMany
34from elixir.properties import has_property, GenericProperty, ColumnProperty
35from elixir.statements import Statement
36
37
38__version__ = '0.4.1'
39
40__all__ = ['Entity', 'EntityMeta',
41           'Field', 'has_field', 'with_fields',
42           'has_property', 'GenericProperty', 'ColumnProperty',
43           'belongs_to', 'has_one', 'has_many', 'has_and_belongs_to_many',
44           'ManyToOne', 'OneToOne', 'OneToMany', 'ManyToMany',
45           'using_options', 'using_table_options', 'using_mapper_options',
46           'options_defaults', 'metadata', 'objectstore', 'session',
47           'create_all', 'drop_all',
48           'setup_all', 'cleanup_all', 
49           'setup_entities', 'cleanup_entities'] + \
50           sqlalchemy.types.__all__
51
52__doc_all__ = ['create_all', 'drop_all',
53               'setup_all', 'cleanup_all',
54               'metadata', 'session']
55
56
57class Objectstore(object):
58    """a wrapper for a SQLAlchemy session-making object, such as
59    SessionContext or ScopedSession.
60   
61    Uses the ``registry`` attribute present on both objects
62    (versions 0.3 and 0.4) in order to return the current
63    contextual session.
64    """
65   
66    def __init__(self, ctx):
67        self.context = ctx
68
69    def __getattr__(self, name):
70        return getattr(self.context.registry(), name)
71   
72    session = property(lambda s:s.context.registry())
73
74# default session
75try: 
76    from sqlalchemy.orm import scoped_session
77    session = scoped_session(sqlalchemy.orm.create_session)
78except ImportError: 
79    # Not on version 0.4 of sqlalchemy
80    from sqlalchemy.ext.sessioncontext import SessionContext
81    session = Objectstore(SessionContext(sqlalchemy.orm.create_session))
82
83# backward-compatible name
84objectstore = session
85
86# default metadata
87metadata = sqlalchemy.MetaData()
88
89metadatas = set()
90
91# default entity collection
92entities = list()
93
94
95def create_all(*args, **kwargs):
96    '''Create the necessary tables for all declared entities'''
97    for md in metadatas:
98        md.create_all(*args, **kwargs)
99
100
101def drop_all(*args, **kwargs):
102    '''Drop tables for all declared entities'''
103    for md in metadatas:
104        md.drop_all(*args, **kwargs)
105
106
107def setup_all(create_tables=False, *args, **kwargs):
108    '''Setup the table and mapper of all entities in the default entity
109    collection.
110
111    This is called automatically if any entity of the collection is configured
112    with the `autosetup` option (this is the default) and it is first accessed,
113    instanciated (called) or the create_all method of a metadata containing
114    tables from any of those entities is called.
115    '''
116    setup_entities(entities)
117
118    # issue the "CREATE" SQL statements
119    if create_tables:
120        create_all(*args, **kwargs)
121
122
123def cleanup_all(drop_tables=False, *args, **kwargs):
124    '''Clear all mappers, clear the session, and clear all metadatas.
125    Optionally drops the tables.
126    '''
127    if drop_tables:
128        drop_all(*args, **kwargs)
129
130    cleanup_entities(entities)
131
132    for md in metadatas:
133        md.clear()
134    metadatas.clear()
135
136    session.clear()
137
138    sqlalchemy.orm.clear_mappers()
139    del entities[:]
Note: See TracBrowser for help on using the browser.