[sqlalchemy] Re: How can I do this relation?

2010-12-01 Thread Jonathan Gardner
On Nov 30, 3:15 pm, Alvaro Reinoso alvrein...@gmail.com wrote:

 One region can just contain one channel, but one channel could be in
 many regions. A region will never be accessed by a channel. However,
 Channel could be accessed by a region, so I need that relationship in
 region. Is that relationship OK? If not, how can I make it?


It's not entirely clear what you are trying to do here. It sounds like
a classic one-to-many relationship without a backref. All you have to
do is get rid of the backref=regions bit and you should be good to
go.

BTW, you probably want to drop the idea of A is accessed by/through
B. It doesn't quite fit with what's really going on in the relational
world. Instead, think of how two independent objects may (or may not)
be related to one another.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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.



[sqlalchemy] Managing transactions from Session using raw_connections

2010-12-01 Thread Ralph Heinkel

Hi everybody,

we have the problem that transactions embedded in
'with Session.begin()'
are not committing statements made in raw connections. However
'with engine.begin()'  (in 0.5.8)
works fine.

The reason we need to use Session.begin() is that we want to cover 
transactions over multiple engines. Raw connections are needed because 
we have to run oracle plsql functions and hence need to call 
'cursor.call(...)'.


Below you find a simple example. It doesn't call a stored procedure, 
but the problem is the same.
By using 'strategy=threadlocal' I would have assumed that I always 
operate on the same low level db connection. This seems to be true 
with 'engine.begin()', but not with 'session.begin()'.


Any idea why?

Thanks for your help,

Ralph


ps: Why did the 'engine.begin()' context manager disappear in 0.6.x?

---

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

engine = create_engine('sqlite:///s.db', strategy='threadlocal', 
echo=True)

Session = scoped_session(sessionmaker(autoflush=True, autocommit=True))

engine.execute('create table testtable (id int, name varchar(20))')
engine.execute(insert into testtable (id, name) values (1, 'otto'))
engine.execute(insert into testtable (id, name) values (2, 'gustav'))

with Session.begin():# does not work
#with engine.begin():# does work !
engine.execute(update testtable set name='ottox28' where id=1)
# the next line returns a low level DBAPI connection obj:
raw_conn = engine.contextual_connect().connection
cur = raw_conn.cursor()
cur.execute(update testtable set name='gustav2' where id=2)


(if you look into s.db with sqlite3 record id=2 is still 'gustav')

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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.



[sqlalchemy] dynamic modification of foreign keys sqlalchemy

2010-12-01 Thread slothy
Hi!

I'm creating a structure of elements dynamically with declarative,
and I'm not sure if I can modify the mapper to get the new elements
related with a FK. Sorry about my english, is very poor.

This is my function class factory:

def nuevaEtiqueta(self, nombre_etiqueta):
etiqueta = nombre_etiqueta.lower().strip()
nombre_etiqueta = etiquetas_ + etiqueta
dicc = {'__tablename__':nombre_etiqueta,'__table_args__ ':
{'autoload':True}}

id = Column(Integer,primary_key=True);dicc.update({'id':id})
tipo = Column(Text);dicc.update({'tipo':tipo})
contenido_texto =
Column(Text);dicc.update({'contenido_texto':contenido_texto})
contenido_binario =
Column(LargeBinary);dicc.update({'contenido_binario':contenido_binario})
fichero = Column(Text);dicc.update({'fichero':fichero})
ref_elemento = Column(Integer,ForeignKey('elementos_'+etiqueta
+'.id'));dicc.update({'ref_elemento':ref_elemento})

def __init__(self, diccio):
  self.tipo = diccio[tipo]
  if self.tipo == BIN:
self.contenido_binario = diccio[contenido_binario]
self.fichero = diccio[fichero]
  else:
self.contenido_texto = diccio[contenido_texto]
dicc.update({'__init__':__init__})

def __repr__(self):
  aux = ETIQUETA 
  if self.tipo == 'BIN':
return aux +  BINARIA
  else:
return aux + %s - CONTENIDO: %s %
(self.tipo,self.contenido_texto)
dicc.update({'__repr__':__repr__})

clase_etiqueta = type(str(nombre_etiqueta),(Base,),dicc)
self.etiquetas_map.update({nombre_etiqueta:clase_etiqueta})

Now, when a new class is created, I want the mapper adds the FK

I'm trying to do this with session mappers but with no success.

Can you help?

Thanks

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] Managing transactions from Session using raw_connections

2010-12-01 Thread Michael Bayer

On Dec 1, 2010, at 5:50 AM, Ralph Heinkel wrote:

 Hi everybody,
 
 we have the problem that transactions embedded in
   'with Session.begin()'
 are not committing statements made in raw connections. However
   'with engine.begin()'  (in 0.5.8)
 works fine.
 
 The reason we need to use Session.begin() is that we want to cover 
 transactions over multiple engines. Raw connections are needed because we 
 have to run oracle plsql functions and hence need to call 'cursor.call(...)'.
 
 Below you find a simple example. It doesn't call a stored procedure, but the 
 problem is the same.
 By using 'strategy=threadlocal' I would have assumed that I always operate on 
 the same low level db connection. This seems to be true with 
 'engine.begin()', but not with 'session.begin()'.
 
 Any idea why?
 
 Thanks for your help,

The Session.begin() statement doesn't touch any of its engines until it 
accesses one of them in order to procure a connection, so engine.execute() 
isn't related to that interaction, hence threadlocal not really of use when 
the Session is used to manage transactions.   See 
http://www.sqlalchemy.org/docs/core/connections.html#using-the-threadlocal-execution-strategy
 for details.

Here you'd use Session.execute() and Session.connection() to get at the 
Connection you'd normally get from engine.contextual_connect() 
(http://www.sqlalchemy.org/docs/orm/session.html#using-sql-expressions-with-sessions)
 .execute() and connection() accept a mapper argument for the case where 
individual engines are associated with individual mappers, and both ultimately 
call get_bind() which you can override via subclass if desired to accept other 
kinds of arguments.



 
 Ralph
 
 
 ps: Why did the 'engine.begin()' context manager disappear in 0.6.x?
 
 ---
 
 from sqlalchemy import create_engine
 from sqlalchemy.orm import scoped_session, sessionmaker
 
 engine = create_engine('sqlite:///s.db', strategy='threadlocal', echo=True)
 Session = scoped_session(sessionmaker(autoflush=True, autocommit=True))
 
 engine.execute('create table testtable (id int, name varchar(20))')
 engine.execute(insert into testtable (id, name) values (1, 'otto'))
 engine.execute(insert into testtable (id, name) values (2, 'gustav'))
 
 with Session.begin():# does not work
 #with engine.begin():# does work !
engine.execute(update testtable set name='ottox28' where id=1)
# the next line returns a low level DBAPI connection obj:
raw_conn = engine.contextual_connect().connection
cur = raw_conn.cursor()
cur.execute(update testtable set name='gustav2' where id=2)
 
 
 (if you look into s.db with sqlite3 record id=2 is still 'gustav')
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@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] finding if a table is already join in a query

2010-12-01 Thread Michael Bayer

On Dec 1, 2010, at 1:28 AM, James Neethling wrote:

 
 if you would like multiple references to Address to all work from the same 
 join, your routine needs to track which entities have already been joined as 
 a destination in a separate collection:
 
 
 def search(columns):
  already_joined = set()
...
if class_ not in already_joined:
  q = q.join(destination)
  already_joined.add(class_)
 
 Hi Michael,
 
 Thank you for the quick response.
 
 Unfortunately we don't always know where this query comes from (my
 example was a little contrived :( )
 
 Is there any way to get the tables that are currently in the join for a
 query?

You can iterate through q._from_obj(), and for each object that is a join(), 
recursively descend through j.left and j.right looking for Table objects. 
Table objects can be embedded in subqueries and alias objects too but I'm 
assuming your query buildup here is simple enough that gray areas like that 
aren't expected.

If it were me, I'd not be passing a raw Query around, I'd have it wrapped 
inside a facade that is doing the abovementioned tracking of important state 
explicitly (and also ensuring that those more grayish areas aren't occurring 
with this particular Query).   That way any other interesting facts about the 
query as built so far can be tracked as well.   Also easier to unit test.



 
 
 Here is a cut down sample implementation that will hopefully remove any
 confusion... Note the TODO: in Employee.search()
 
 ---8---8---8
 
 from sqlalchemy import create_engine, Column, ForeignKey, or_
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.orm import scoped_session, sessionmaker, relationship,
 joinedload
 from sqlalchemy.types import Integer, String, Text
 from sqlalchemy.sql.expression import cast
 
 engine = create_engine('sqlite:///:memory:', echo=True)
 Base = declarative_base(bind=engine)
 Session = scoped_session(sessionmaker(bind=engine))
 
 
 class Employee(Base):
   __tablename__ = 'employee'
   id = Column(Integer, primary_key=True)
   name = Column(String)
 
   def search(self, value, columns):
 query = Session.query(Employee)
   for i, column in enumerate(columns):
   model = column.parententity.class_
   if Employee is not model:
 #TODO: Are we already joined from Employee onto model?
   query = query.outerjoin(model)
   args = [cast(c, Text).ilike('%%%s%%' % value) for c in columns]
   return query.filter(or_(*args))
 
 class Address(Base):
   __tablename__ = 'address'
   id = Column(Integer, primary_key=True)
   employee_id = Column(Integer, ForeignKey(Employee.id))
   street1 =  Column(String(50))
   street2 =  Column(String(50))
   employee = relationship(Employee)
 
 Base.metadata.create_all()
 
 
 #e = Employee(name='Bob')
 #a = Address(employee=e, street1='street1', street2='street2')
 #Session.add(a)
 #Session.commit()
 
 
 q = Employee().search('stree', [Employee.name, Address.street1,
 Address.street2])
 print q
 
 SELECT employee.id AS employee_id, employee.name AS employee_name 
 FROM employee LEFT OUTER JOIN address ON employee.id =
 address.employee_id LEFT OUTER JOIN address ON employee.id =
 address.employee_id 
 WHERE lower(CAST(employee.name AS TEXT)) LIKE lower(?) OR
 lower(CAST(address.street1 AS TEXT)) LIKE lower(?) OR
 lower(CAST(address.street2 AS TEXT)) LIKE lower(?)
 
 ---8---8---8
 
 TIA
 Jim
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@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.
 
 
 
 -- 
 James Neethling
 Development Manager
 XO Africa Safari
 (t) +27 21 486 2700 (ext. 127)
 (e) jam...@xoafrica.com
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 

Re: [sqlalchemy] dynamic modification of foreign keys sqlalchemy

2010-12-01 Thread Michael Bayer

On Dec 1, 2010, at 5:40 AM, slothy wrote:

 Hi!
 
 I'm creating a structure of elements dynamically with declarative,
 and I'm not sure if I can modify the mapper to get the new elements
 related with a FK. Sorry about my english, is very poor.
 
 This is my function class factory:
 
 def nuevaEtiqueta(self, nombre_etiqueta):
etiqueta = nombre_etiqueta.lower().strip()
nombre_etiqueta = etiquetas_ + etiqueta
dicc = {'__tablename__':nombre_etiqueta,'__table_args__ ':
 {'autoload':True}}
 
id = Column(Integer,primary_key=True);dicc.update({'id':id})
tipo = Column(Text);dicc.update({'tipo':tipo})
contenido_texto =
 Column(Text);dicc.update({'contenido_texto':contenido_texto})
contenido_binario =
 Column(LargeBinary);dicc.update({'contenido_binario':contenido_binario})
fichero = Column(Text);dicc.update({'fichero':fichero})
ref_elemento = Column(Integer,ForeignKey('elementos_'+etiqueta
 +'.id'));dicc.update({'ref_elemento':ref_elemento})
 
def __init__(self, diccio):
  self.tipo = diccio[tipo]
  if self.tipo == BIN:
self.contenido_binario = diccio[contenido_binario]
self.fichero = diccio[fichero]
  else:
self.contenido_texto = diccio[contenido_texto]
dicc.update({'__init__':__init__})
 
def __repr__(self):
  aux = ETIQUETA 
  if self.tipo == 'BIN':
return aux +  BINARIA
  else:
return aux + %s - CONTENIDO: %s %
 (self.tipo,self.contenido_texto)
dicc.update({'__repr__':__repr__})
 
clase_etiqueta = type(str(nombre_etiqueta),(Base,),dicc)
self.etiquetas_map.update({nombre_etiqueta:clase_etiqueta})
 
 Now, when a new class is created, I want the mapper adds the FK
 
 I'm trying to do this with session mappers but with no success.

you can add a Foreign key to a Table using:

table.append_constraint(ForeignKeyConstraint(('local_col', ), 
('remote_table.remote_col', ))

you'd build functionality which does this at the same time as creating mappers. 
  





 
 Can you help?
 
 Thanks
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@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.



[sqlalchemy] Weird behavior

2010-12-01 Thread Alvaro Reinoso
Hello,

I have a system to manage users in my application, but I'm getting
some troubles with it.

Every user has to belong to a group of users. One user can only be in
one group.

I have those tables (inheriting from rdb.Model is basically the same
thing than using sqlalchemy's declarative model)

class User(rdb.Model):
Represents the user
rdb.metadata(metadata)
rdb.tablename(users)

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


userGroup = relationship(UserGroup, uselist=False)
.

class UserGroup(rdb.Model):
Represents a group of users with the same features
rdb.metadata(metadata)
rdb.tablename(user_groups)

id = Column(id, Integer, primary_key=True)
title = Column(title, String(50))

users = relationship(User, order_by=User.name, cascade=all,
delete, delete-orphan, backref=user_groups)


I have a script which migrate users from a pre-existing Zope DB
(object-oriented):

def migrateUsers():
Migrate all the users to the database
session = rdb.Session()
rScreens = session.query(Screen).all()
rUserGroups = session.query(UserGroup).all()
.

for oldUser in grok.getSite()['Users'].values():
user = User()
..
for newGroup in rUserGroups:
if newGroup.title == superadmins:
newGroup.users.append(user)
..

return

When I execute the script, the user_groups are properly created and
the users are properly added to the user_groups they should belong to,
but I get empty group entries in the database, and I don't know why

I have made some tests, and I've realized that I get an empty entry
(an empty user_group) every time I try to add a user to a user_group,
but I don't know what is causing this behavior.

Any hint will be appreciated.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] Weird behavior

2010-12-01 Thread Michael Bayer

On Dec 1, 2010, at 5:46 PM, Alvaro Reinoso wrote:

 Hello,
 
 I have a system to manage users in my application, but I'm getting
 some troubles with it.
 
 Every user has to belong to a group of users. One user can only be in
 one group.
 
 I have those tables (inheriting from rdb.Model is basically the same
 thing than using sqlalchemy's declarative model)
 
 class User(rdb.Model):
   Represents the user
   rdb.metadata(metadata)
   rdb.tablename(users)
 
   id = Column(id, Integer, primary_key=True)
   name = Column(name, String(50))

 
   userGroup = relationship(UserGroup, uselist=False)
.
 
 class UserGroup(rdb.Model):
   Represents a group of users with the same features
   rdb.metadata(metadata)
   rdb.tablename(user_groups)
 
   id = Column(id, Integer, primary_key=True)
   title = Column(title, String(50))
 
   users = relationship(User, order_by=User.name, cascade=all,
 delete, delete-orphan, backref=user_groups)

 
 I have a script which migrate users from a pre-existing Zope DB
 (object-oriented):
 
 def migrateUsers():
   Migrate all the users to the database
   session = rdb.Session()
   rScreens = session.query(Screen).all()
   rUserGroups = session.query(UserGroup).all()
.
 
   for oldUser in grok.getSite()['Users'].values():
   user = User()
   ..
   for newGroup in rUserGroups:
   if newGroup.title == superadmins:
   newGroup.users.append(user)
..
 
   return
 
 When I execute the script, the user_groups are properly created and
 the users are properly added to the user_groups they should belong to,
 but I get empty group entries in the database, and I don't know why
 
 I have made some tests, and I've realized that I get an empty entry
 (an empty user_group) every time I try to add a user to a user_group,
 but I don't know what is causing this behavior.

theres no instantiation of UserGroup indicated above so no indication of what 
would be creating extra group rows in your database.




 
 Any hint will be appreciated.
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@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.