Search code examples
pythonsqlalchemycrudpython-elixir

Is Python Camelot tied to Elixir?


The docs for Camelot say that it uses Elixir models. Since SQLAlchemy has included declarative_base for a while, I had used that instead of Elixir for another app. Now I would like to use the SQLAlchemy/declarative models directly in Camelot.

There is a post on Stackoverflow that says Camelot is not tied to Elixir and that using different models would be possible but it doesn't say how.

Camelot's original model.py only has this content:

import camelot.types
from camelot.model import metadata, Entity, Field, ManyToOne, OneToMany, Unicode, Date, Integer, using_options
from camelot.view.elixir_admin import EntityAdmin
from camelot.view.forms import *

__metadata__ = metadata

I added my SQLAlchemy model and changed model.py to this:

import camelot.types
from camelot.model import metadata, Entity, Field, ManyToOne, OneToMany, Unicode, Date, using_options
from camelot.view.elixir_admin import EntityAdmin
from camelot.view.forms import *

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

__metadata__ = metadata
Base = declarative_base()

class Test(Base):
    __tablename__ = "test"
    id = Column(Integer, primary_key=True)
    text = Column(String)

It didn't work. When I start main.py, I can see the GUI and Test in the sidebar, but can't see any rows. This is the tail of the traceback:

File "/usr/lib/python2.6/dist-packages/camelot/view/elixir_admin.py", line 52, in get_query
    return self.entity.query
AttributeError: type object 'Test' has no attribute 'query'

This is the elixir_admin.py code for line 46-52:

@model_function
def get_query(self):
    """:return: an sqlalchemy query for all the objects that should be
    displayed in the table or the selection view.  Overwrite this method to
    change the default query, which selects all rows in the database.
    """
    return self.entity.query

If this code is causing the problem, how do I overwrite the method to change the default query to make it work?

How can you use SQLAlchemy/declarative models in Camelot?


Solution

  • Here is some sample code on using Declarative to define a Movie model for Camelot, some explanation can be found here.

    import sqlalchemy.types
    from sqlalchemy import Column
    from sqlalchemy.ext.declarative import ( declarative_base, 
                                             _declarative_constructor )
    
    from camelot.admin.entity_admin import EntityAdmin
    from camelot.model import metadata
    import camelot.types
    
    from elixir import session
    
    class Entity( object ):
    
        def __init__( self, **kwargs ):
            _declarative_constructor( self, **kwargs )
            session.add( self )
    
    Entity = declarative_base( cls = Entity, 
                               metadata = metadata,
                               constructor = None )
    
    class Movie( Entity ):
    
        __tablename__ = 'movie'
    
        id = Column( sqlalchemy.types.Integer, primary_key = True )
        name = Column( sqlalchemy.types.Unicode(50), nullable = False )
        cover = Column( camelot.types.Image(), nullable = True )
    
        class Admin( EntityAdmin ):
            list_display = ['name']
            form_display = ['name', 'cover']