[sqlalchemy] dynamic classes and tables

2011-02-08 Thread farcat
Hi everyone,

I am new to sqlalchemy and figuring out whether it is right for my
project. What I am looking for is the ability to change classes and
tables on the flight, with as much freedom as possible, potentially
having metaclasses figuring out the difference between versions and
updating the database accordingly. Additionally I would like to import
databases and automatically generate class definitions. Some code I
tried:

code
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relation, sessionmaker

Base = declarative_base()

def Init(self, title=None, year=None):
self.title = title
self.year = year
def Repr(self):
return Movie(%r, %r, %r) % (self.title, self.year,
self.director)

Movie = type(Movie, (Base,),{'__tablename__': movies,
id:Column(Integer, primary_key=True),
title: Column(String(255), nullable=False),
year: Column(Integer),
directed_by: Column(Integer,
ForeignKey('directors.id')),
director: relation(Director, backref='movies',
lazy=False)})
setattr(Movie, __init__, classmethod(Init))
setattr(Movie, __repr__, classmethod(Repr))


class Director(Base):
__tablename__ = 'directors'

id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False, unique=True)

def __init__(self, name=None):
self.name = name

def __repr__(self):
return Director(%r) % (self.name)

engine = create_engine('sqlite:///meta.db', echo=True)
Base.metadata.create_all(engine)

if __name__ == __main__:
Session = sessionmaker(bind=engine)
session = Session()

m1 = Movie(Star Trek, 2009)
m1.director = Director(JJ Abrams)

d2 = Director(George Lucas)
d2.movies = [Movie(Star Wars, 1977), Movie(THX 1138, 1971)]

try:
session.add(m1)
session.add(d2)
session.commit()
except:
session.rollback()

alldata = session.query(Movie).all()
for somedata in alldata:
print somedata

\code

with as error:


2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L
PRAGMA table_info(directors)
2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L
()
Traceback (most recent call last):
  File D:\Documents\Code\NetBeans\test\alchemy\src\alchemy.py, line
49, in module
m1.director = Director(JJ Abrams)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py,
line 158, in __set__
2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L
PRAGMA table_info(movies)
2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L
()
self.impl.set(instance_state(instance),
AttributeError: 'Movie' object has no attribute '_sa_instance_state'

Can anyone shed some light or explain the error message?

-- 
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] dynamic classes and tables

2011-02-08 Thread Michael Bayer

On Feb 8, 2011, at 3:52 PM, farcat wrote:

 Hi everyone,
 
 I am new to sqlalchemy and figuring out whether it is right for my
 project. What I am looking for is the ability to change classes and
 tables on the flight, with as much freedom as possible, potentially
 having metaclasses figuring out the difference between versions and
 updating the database accordingly. Additionally I would like to import
 databases and automatically generate class definitions. Some code I
 tried:
 
 code
 from sqlalchemy import *
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.orm import relation, sessionmaker
 
 Base = declarative_base()
 
 def Init(self, title=None, year=None):
self.title = title
self.year = year
 def Repr(self):
return Movie(%r, %r, %r) % (self.title, self.year,
 self.director)
 
 Movie = type(Movie, (Base,),{'__tablename__': movies,
id:Column(Integer, primary_key=True),
title: Column(String(255), nullable=False),
year: Column(Integer),
directed_by: Column(Integer,
 ForeignKey('directors.id')),
director: relation(Director, backref='movies',
 lazy=False)})
 setattr(Movie, __init__, classmethod(Init))
 setattr(Movie, __repr__, classmethod(Repr))
 
 
 class Director(Base):
__tablename__ = 'directors'
 
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False, unique=True)
 
def __init__(self, name=None):
self.name = name
 
def __repr__(self):
return Director(%r) % (self.name)
 
 engine = create_engine('sqlite:///meta.db', echo=True)
 Base.metadata.create_all(engine)
 
 if __name__ == __main__:
Session = sessionmaker(bind=engine)
session = Session()
 
m1 = Movie(Star Trek, 2009)
m1.director = Director(JJ Abrams)
 
d2 = Director(George Lucas)
d2.movies = [Movie(Star Wars, 1977), Movie(THX 1138, 1971)]
 
try:
session.add(m1)
session.add(d2)
session.commit()
except:
session.rollback()
 
alldata = session.query(Movie).all()
for somedata in alldata:
print somedata
 
 \code
 
 with as error:
 
 
 2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L
 PRAGMA table_info(directors)
 2011-02-08 21:50:47,553 INFO sqlalchemy.engine.base.Engine.0x...ef0L
 ()
 Traceback (most recent call last):
  File D:\Documents\Code\NetBeans\test\alchemy\src\alchemy.py, line
 49, in module
m1.director = Director(JJ Abrams)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py,
 line 158, in __set__
 2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L
 PRAGMA table_info(movies)
 2011-02-08 21:50:47,555 INFO sqlalchemy.engine.base.Engine.0x...ef0L
 ()
self.impl.set(instance_state(instance),
 AttributeError: 'Movie' object has no attribute '_sa_instance_state'
 
 Can anyone shed some light or explain the error message?

your __init__ monkeypatch is interfering with SQLA's wrapping of this method.

Try

Movie = type(Movie, (Base,),{'__tablename__': movies,
__init__:Init,
   id:Column(Integer, primary_key=True),
   title: Column(String(255), nullable=False),
   year: Column(Integer),
   directed_by: Column(Integer,ForeignKey('directors.id')),
   director: relation(Director, 
backref='movies',lazy=False)})


instead.



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