Re: [sqlalchemy] Re: negative implications of using multiple declarative Base classes
avdd wrote: I'm glad you brought this up. It seems to me that the the declarative instrumentation keys classes by their unqualified class name, precluding using the same class name for different declarative subclasses (ie, in different modules). Indeed, but I suspect there's more to it than that. My guess would be that you'd then have to use the full dotted name to the class, which might be problematic. Myself, I wish we could drop the need for the registry in the declarative base and push all the required info down into the MetaData object. What would be the problems with doing this? Chris -- Simplistix - Content Management, Batch Processing Python Consulting - http://www.simplistix.co.uk -- 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] Session uses new connection after commit
Hi, I'm using PostgreSQL advisory locks in a multithreaded program. Worker threads acquire locks with session.execute(select([func.pg_advisory_lock(key)])) during a transaction and release them just after session.commit(). Sometimes however, the connection behind the thread's session will have changed after COMMIT, making it impossible for the thread to release the locks it acquired. Note that I'm using scoped_session()'s class methods everywhere. A python script to reproduce the problem and its output are attached below. Is there a way to force the session to use the same connection within a thread ? Would I then have to recycle the connections from time to time ? Thanks, Julien === sa_pg_advisory_locks.py == # -*- coding: utf8 -*- import random import os import threading import time from sqlalchemy import MetaData from sqlalchemy.engine import create_engine from sqlalchemy.orm import create_session, scoped_session, sessionmaker, reconstructor from sqlalchemy.sql import func, select sa_engine = create_engine(os.environ['TEST_DSN']) session = scoped_session(lambda: create_session(sa_engine, autoflush=True, expire_on_commit=True, autocommit=False)) # Toggle this switch to see the difference in behaviour COMMIT_BEFORE_LOCK_RELEASE = True # COMMIT_BEFORE_LOCK_RELEASE = False print 'Will commit %s releasing advisory lock' % ('before' if COMMIT_BEFORE_LOCK_RELEASE else 'after') # Synchronize program termination event = threading.Event() # Test function, will run concurrently in two threads def run_test(): try: i = 0 while 1: if event.isSet() or i = 100: break # Show sign of life if i and (i % 50 == 0): print i key = random.randint(1,2**16) pid, _ = session.execute(select([func.pg_backend_pid(), func.pg_advisory_lock(key)])).fetchone() now = session.execute(select([func.now()])).scalar() if COMMIT_BEFORE_LOCK_RELEASE: session.commit() pid_, unlocked = session.execute(select([func.pg_backend_pid(), func.pg_advisory_unlock(key)])).fetchone() if unlocked: assert pid_ == pid else: raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) if not COMMIT_BEFORE_LOCK_RELEASE: session.commit() i += 1 except Exception: event.set() raise event.set() for i in xrange(10): thread = threading.Thread(target=run_test) thread.daemon = True thread.start() event.wait() time.sleep(1) == output == u...@host ~ $ TEST_DSN=$CPYTHON_DSN python sa_pg_advisory_locks.py Will commit before releasing advisory lock Exception in thread Thread-10: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 6, acquisition pid 16676, release pid 27340 Exception in thread Thread-5: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 12, acquisition pid 27340, release pid 16676 Exception in thread Thread-7: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 10, acquisition pid 18248, release pid 8452 Exception in thread Thread-3: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 18, acquisition pid 8452, release pid 18248 u...@host ~ $
[sqlalchemy] where would you store meta data .. ?
Hello, I'm building a CMS-like webapp where I use inheritance a lot. One feature that I would like to allow is that when an user add a new section (a new container), he would be able to select the default with_polymorphic() clause, order_by, objects per page when browsing the container, etc. I wondered where is the best place to store those meta data (in the database itself ? in a separate table ? .. ?), and in which format (JSON ? serialized object ? ... ?) ? I would like to avoid a seqscan of a lot of rows and any breakage when, for example, a mapped child class (polymorphic_identity) is removed, but was selected for a polymorphic loading in one or more containers. I don't know if this is the best place to ask but ... let's try :-) Thanks, Julien -- No trees were killed in the creation of this message. However, many electrons were terribly inconvenienced. -- 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. attachment: jcigar.vcf
[sqlalchemy] begginers query question
Hi guys. I've got a little problem with the sqlalchemy syntax. I've got two tables with relations: Table_Goups id int(4) PrimaryKey not null, name varchar(50) not null; and Table_User id int(4) Primary Key not null, login varchar(50) not null, id_group int(4) Foreign Key not null; i would like to build a query that would gets the user data from Table_User and the id_group but insted od showing the id_group number i want to show the Table_Groups.name Can anyone help? -- 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] Re: negative implications of using multiple declarative Base classes
On Aug 24, 2010, at 3:04 AM, Chris Withers wrote: avdd wrote: I'm glad you brought this up. It seems to me that the the declarative instrumentation keys classes by their unqualified class name, precluding using the same class name for different declarative subclasses (ie, in different modules). Indeed, but I suspect there's more to it than that. My guess would be that you'd then have to use the full dotted name to the class, which might be problematic. Myself, I wish we could drop the need for the registry in the declarative base and push all the required info down into the MetaData object. What would be the problems with doing this? breaks encapsulation. Chris -- Simplistix - Content Management, Batch Processing Python Consulting - http://www.simplistix.co.uk -- 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] Session uses new connection after commit
On Aug 24, 2010, at 6:12 AM, Julien Demoor wrote: Hi, I'm using PostgreSQL advisory locks in a multithreaded program. Worker threads acquire locks with session.execute(select([func.pg_advisory_lock(key)])) during a transaction and release them just after session.commit(). Sometimes however, the connection behind the thread's session will have changed after COMMIT, making it impossible for the thread to release the locks it acquired. Note that I'm using scoped_session()'s class methods everywhere. A python script to reproduce the problem and its output are attached below. Is there a way to force the session to use the same connection within a thread ? Would I then have to recycle the connections from time to time ? I think the most direct way is to bind the Session to a specific connection: conn = engine.connect() sess = Session(bind=conn) then when the scope of work with the connection is complete: sess.close() conn.close() the indirect way would be to play games with the connection pool, but in this case your application should already have explicit boundaries where you'd like this connection to stay in play so the above approach is straightforward. Thanks, Julien === sa_pg_advisory_locks.py == # -*- coding: utf8 -*- import random import os import threading import time from sqlalchemy import MetaData from sqlalchemy.engine import create_engine from sqlalchemy.orm import create_session, scoped_session, sessionmaker, reconstructor from sqlalchemy.sql import func, select sa_engine = create_engine(os.environ['TEST_DSN']) session = scoped_session(lambda: create_session(sa_engine, autoflush=True, expire_on_commit=True, autocommit=False)) # Toggle this switch to see the difference in behaviour COMMIT_BEFORE_LOCK_RELEASE = True # COMMIT_BEFORE_LOCK_RELEASE = False print 'Will commit %s releasing advisory lock' % ('before' if COMMIT_BEFORE_LOCK_RELEASE else 'after') # Synchronize program termination event = threading.Event() # Test function, will run concurrently in two threads def run_test(): try: i = 0 while 1: if event.isSet() or i = 100: break # Show sign of life if i and (i % 50 == 0): print i key = random.randint(1,2**16) pid, _ = session.execute(select([func.pg_backend_pid(), func.pg_advisory_lock(key)])).fetchone() now = session.execute(select([func.now()])).scalar() if COMMIT_BEFORE_LOCK_RELEASE: session.commit() pid_, unlocked = session.execute(select([func.pg_backend_pid(), func.pg_advisory_unlock(key)])).fetchone() if unlocked: assert pid_ == pid else: raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) if not COMMIT_BEFORE_LOCK_RELEASE: session.commit() i += 1 except Exception: event.set() raise event.set() for i in xrange(10): thread = threading.Thread(target=run_test) thread.daemon = True thread.start() event.wait() time.sleep(1) == output == u...@host ~ $ TEST_DSN=$CPYTHON_DSN python sa_pg_advisory_locks.py Will commit before releasing advisory lock Exception in thread Thread-10: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 6, acquisition pid 16676, release pid 27340 Exception in thread Thread-5: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 12, acquisition pid 27340, release pid 16676 Exception in thread Thread-7: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_))
Re: [sqlalchemy] begginers query question
Hi, On 24/08/2010 10:14, Dobrysmak wrote: Hi guys. I've got a little problem with the sqlalchemy syntax. I've got two tables with relations: Table_Goups id int(4) PrimaryKey not null, name varchar(50) not null; and Table_User id int(4) Primary Key not null, login varchar(50) not null, id_group int(4) Foreign Key not null; i would like to build a query that would gets the user data from Table_User and the id_group but insted od showing the id_group number i want to show the Table_Groups.name Can anyone help? I use SA declarative, so you would define something like this in your model: class Group(Base): __table__ = sa.Table(u'groups', metadata, sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), primary_key=True, nullable=False), sa.Column(u'name', sa.String(length=70, convert_unicode=False), nullable=False), ) class User(Base): __table__ = sa.Table(u'users', metadata, sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), primary_key=True, nullable=False), sa.Column(u'name', sa.String(length=70, convert_unicode=False), nullable=False), sa.Column(u'fk_group', sa.Integer(), sa.ForeignKey(u'groups.id'), nullable=False), ) group = sao.relation('Group', backref='user') And then to query you could do e.g. this: for usr in session.query(db.User).all(): print 'user: %s, group name: %s' % (usr.name, usr.group.name) Check out the SA doc, especially the tutorials: http://www.sqlalchemy.org/docs/ormtutorial.html http://www.sqlalchemy.org/docs/ormtutorial.html#creating-table-class-and-mapper-all-at-once-declaratively Hope this helps Werner -- 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] begginers query question
On 24/08/2010 15:53, werner wrote: Hi, On 24/08/2010 10:14, Dobrysmak wrote: Hi guys. I've got a little problem with the sqlalchemy syntax. I've got two tables with relations: Table_Goups id int(4) PrimaryKey not null, name varchar(50) not null; and Table_User id int(4) Primary Key not null, login varchar(50) not null, id_group int(4) Foreign Key not null; i would like to build a query that would gets the user data from Table_User and the id_group but insted od showing the id_group number i want to show the Table_Groups.name Can anyone help? I use SA declarative, so you would define something like this in your model: class Group(Base): __table__ = sa.Table(u'groups', metadata, sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), primary_key=True, nullable=False), sa.Column(u'name', sa.String(length=70, convert_unicode=False), nullable=False), ) Oops, a copy/paste error, should be: sa.Sequence('gen_group_id') class User(Base): __table__ = sa.Table(u'users', metadata, sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), primary_key=True, nullable=False), and another one, a copy/paste error, should be: sa.Sequence('gen_user_id') sa.Column(u'name', sa.String(length=70, convert_unicode=False), nullable=False), sa.Column(u'fk_group', sa.Integer(), sa.ForeignKey(u'groups.id'), nullable=False), ) group = sao.relation('Group', backref='user') And then to query you could do e.g. this: for usr in session.query(db.User).all(): print 'user: %s, group name: %s' % (usr.name, usr.group.name) Check out the SA doc, especially the tutorials: http://www.sqlalchemy.org/docs/ormtutorial.html http://www.sqlalchemy.org/docs/ormtutorial.html#creating-table-class-and-mapper-all-at-once-declaratively Hope this helps Werner -- 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] Re: Session uses new connection after commit
Thanks a lot, that solves my problem. Also it seems to work well without instantiating the scoped session, so this is perfect. On Aug 24, 3:13 pm, Michael Bayer mike...@zzzcomputing.com wrote: On Aug 24, 2010, at 6:12 AM, Julien Demoor wrote: Hi, I'm using PostgreSQL advisory locks in a multithreaded program. Worker threads acquire locks with session.execute(select([func.pg_advisory_lock(key)])) during a transaction and release them just after session.commit(). Sometimes however, the connection behind the thread's session will have changed after COMMIT, making it impossible for the thread to release the locks it acquired. Note that I'm using scoped_session()'s class methods everywhere. A python script to reproduce the problem and its output are attached below. Is there a way to force the session to use the same connection within a thread ? Would I then have to recycle the connections from time to time ? I think the most direct way is to bind the Session to a specific connection: conn = engine.connect() sess = Session(bind=conn) then when the scope of work with the connection is complete: sess.close() conn.close() the indirect way would be to play games with the connection pool, but in this case your application should already have explicit boundaries where you'd like this connection to stay in play so the above approach is straightforward. Thanks, Julien === sa_pg_advisory_locks.py == # -*- coding: utf8 -*- import random import os import threading import time from sqlalchemy import MetaData from sqlalchemy.engine import create_engine from sqlalchemy.orm import create_session, scoped_session, sessionmaker, reconstructor from sqlalchemy.sql import func, select sa_engine = create_engine(os.environ['TEST_DSN']) session = scoped_session(lambda: create_session(sa_engine, autoflush=True, expire_on_commit=True, autocommit=False)) # Toggle this switch to see the difference in behaviour COMMIT_BEFORE_LOCK_RELEASE = True # COMMIT_BEFORE_LOCK_RELEASE = False print 'Will commit %s releasing advisory lock' % ('before' if COMMIT_BEFORE_LOCK_RELEASE else 'after') # Synchronize program termination event = threading.Event() # Test function, will run concurrently in two threads def run_test(): try: i = 0 while 1: if event.isSet() or i = 100: break # Show sign of life if i and (i % 50 == 0): print i key = random.randint(1,2**16) pid, _ = session.execute(select([func.pg_backend_pid(), func.pg_advisory_lock(key)])).fetchone() now = session.execute(select([func.now()])).scalar() if COMMIT_BEFORE_LOCK_RELEASE: session.commit() pid_, unlocked = session.execute(select([func.pg_backend_pid(), func.pg_advisory_unlock(key)])).fetchone() if unlocked: assert pid_ == pid else: raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) if not COMMIT_BEFORE_LOCK_RELEASE: session.commit() i += 1 except Exception: event.set() raise event.set() for i in xrange(10): thread = threading.Thread(target=run_test) thread.daemon = True thread.start() event.wait() time.sleep(1) == output == u...@host ~ $ TEST_DSN=$CPYTHON_DSN python sa_pg_advisory_locks.py Will commit before releasing advisory lock Exception in thread Thread-10: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 6, acquisition pid 16676, release pid 27340 Exception in thread Thread-5: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484, in run self.__target(*self.__args, **self.__kwargs) File sa_pg_advisory_locks.py, line 44, in run_test raise AssertionError('Iteration %i, acquisition pid %i, release pid %i\n' % (i, pid, pid_)) AssertionError: Iteration 12, acquisition pid 27340, release pid 16676 Exception in thread Thread-7: Traceback (most recent call last): File /usr/lib/python2.6/threading.py, line 532, in __bootstrap_inner self.run() File /usr/lib/python2.6/threading.py, line 484,
[sqlalchemy] TypeDecorator Problem with basic association pattern
Hello, I am trying to reflect the example from http://hg.sqlalchemy.org/sqlalchemy/file/04c17c7d88d6/examples/association/basic_association.py but with my own data structures. I want to manage nutrients, nutrient values and nutrition lists. Therefore I have created a custom data type weight which helps me doing calculations with weights in different units. The relation between nutrients and nutrition lists is m:n, one list can have many nutrients and nutrients can be in many lists. The association table (nutrition values) stores the amount of a nutrient associated to one list. I think I got things working mostly, but flushing my data to the database breaks the program: http://paste.pocoo.org/show/253961/ From what I understand from the message, there seems to be a problem with my custom data type. Maybe someone with more skill in sqlalchemy than me can shed some light on the matter ... Here's the full script http://paste.pocoo.org/show/253956/ Many thanks Frank -- 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] TypeDecorator Problem with basic association pattern
On Aug 24, 2010, at 11:03 AM, Frank wrote: Hello, I am trying to reflect the example from http://hg.sqlalchemy.org/sqlalchemy/file/04c17c7d88d6/examples/association/basic_association.py but with my own data structures. I want to manage nutrients, nutrient values and nutrition lists. Therefore I have created a custom data type weight which helps me doing calculations with weights in different units. The relation between nutrients and nutrition lists is m:n, one list can have many nutrients and nutrients can be in many lists. The association table (nutrition values) stores the amount of a nutrient associated to one list. I think I got things working mostly, but flushing my data to the database breaks the program: http://paste.pocoo.org/show/253961/ From what I understand from the message, there seems to be a problem with my custom data type. Maybe someone with more skill in sqlalchemy than me can shed some light on the matter ... Here's the full script http://paste.pocoo.org/show/253956/ the TypeDecorator just needs to handle the case where the bind or result value is None: class WeightType(types.TypeDecorator): impl = types.Numeric def process_bind_param(self, weight, dialect): if weight is None: return None return weight.base_value def process_result_value(self, value, dialect): if value is None: return None return Weight(value, g) script runs fine after that. You probably meant to name the nutrient_weight column as weight, or otherwise remap the attribute on the NutritionValue class mapper with that name. Many thanks Frank -- 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] upgrading code with prop.backref from 0.5 - 0.6
On Sat, Aug 21, 2010 at 01:45:48PM -0400, Michael Bayer wrote: columns in a property column = prop.columns[0] props = [] for pr in mapper.iterate_properties: if isinstance(pr, properties.RelationProperty): if pr.direction.name in ('MANYTOONE',): for col in pr.local_remote_pairs[0]: # I can't use col in p.local_remote_pairs # as it uses 'col == p.local_remote_pairs' that evaluates # to a BinaryExpression if column is col: try: if pr.backref.prop.cascade.delete_orphan: props += [pr] except AttributeError, e: pass return tuple(props) This fails in sqla 0.6 as pr.backref is empty. Which is the correct way to get the properties that have a backref that have cascade with delete_orphan? why not put some info on the director_id column (i.e. Column(, info={'foo':'bar'}) ) that gives your application the information what you need in a succinct and direct way. There's no public API that links relationships to backrefs and the poking through lists of columns is hacky too. I could tell you where they're linked but it can change at any time. I wasn't aware of 'info' option. I do appreciate how easy it is to implement it this way. On the other hand the other approch didn't even need special configuration. Info option is clearly very handy. At the moment I implemented an image field in sqlkit, (that's just a bunch of handler in the gui). In order to do that I used a type inherited with no addition, just to understand that that field is the path to an Image: class Image(String): pass clearly another alternative would be to use info={ 'image': true} or similar. Is there some caveat that would make one preferred over the other? TIA sandro *:-) -- Sandro Dentella *:-) http://sqlkit.argolinux.orgSQLkit home page - PyGTK/python/sqlalchemy -- 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] orm object, before after
I'm holding an orm object that will have changes made to it. Once done it will be passed to the business logic layer that will have to make decisions from the before and after state of the object... What's the best way to get an object, save its state ('before'), modify it ('after) without any chance of the modifications creeping into the before? Assume both copies are from the same session. Thanks, Michael -- 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] orm object, before after
On Aug 24, 2010, at 2:08 PM, Michael Hipp wrote: I'm holding an orm object that will have changes made to it. Once done it will be passed to the business logic layer that will have to make decisions from the before and after state of the object... What's the best way to get an object, save its state ('before'), modify it ('after) without any chance of the modifications creeping into the before? Assume both copies are from the same session. You'd probably call session.flush() (or commit(), depending on how you are scoping your transaction around this operation) before you do anything to it. Then, if you'd like the subsequent modifications to not go to the database at all until some later point, you'd proceed with your subsequent operations with autoflush turned off - recipes for that are at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush . Thanks, Michael -- 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] Extending DeclarativeBase
Greetings, I was playing around and trying to extend the DeclarativeBase with some Elixir like functions... I may be to green in Python itself that I'm missing something though, here's what I got... class ModelBase(DeclarativeMeta): @classmethod def get(cls, id): row = meta.Session.query(cls).filter_by(id=id).one() return row DeclarativeBase = declarative_base(metaclass=ModelBase) metadata = DeclarativeBase.metadata uhhh... so how does the introspection work here (if any)? I'm I a bit too naive here? calling cls.__class__, cls.__table__, or cls.__call__() doesn't seem to do it... -- 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] orm object, before after
On 8/24/2010 1:51 PM, Michael Bayer wrote: On Aug 24, 2010, at 2:08 PM, Michael Hipp wrote: I'm holding an orm object that will have changes made to it. Once done it will be passed to the business logic layer that will have to make decisions from the before and after state of the object... What's the best way to get an object, save its state ('before'), modify it ('after) without any chance of the modifications creeping into the before? Assume both copies are from the same session. You'd probably call session.flush() (or commit(), depending on how you are scoping your transaction around this operation) before you do anything to it. Then, if you'd like the subsequent modifications to not go to the database at all until some later point, you'd proceed with your subsequent operations with autoflush turned off - recipes for that are at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush . Thank you. But I didn't understand any of that ... at least as it relates to my question. How do I make a copy of an orm object such that modifications to the copy do not affect the original? (Obviously I could detach one of them, but then it becomes useless as none of the attributes can be accessed.) Could you perhaps repeat the answer in baby-talk language? Thanks, Michael -- 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] orm object, before after
Michael Hipp wrote: On 8/24/2010 1:51 PM, Michael Bayer wrote: On Aug 24, 2010, at 2:08 PM, Michael Hipp wrote: I'm holding an orm object that will have changes made to it. Once done it will be passed to the business logic layer that will have to make decisions from the before and after state of the object... What's the best way to get an object, save its state ('before'), modify it ('after) without any chance of the modifications creeping into the before? Assume both copies are from the same session. You'd probably call session.flush() (or commit(), depending on how you are scoping your transaction around this operation) before you do anything to it. Then, if you'd like the subsequent modifications to not go to the database at all until some later point, you'd proceed with your subsequent operations with autoflush turned off - recipes for that are at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush . Thank you. But I didn't understand any of that ... at least as it relates to my question. How do I make a copy of an orm object such that modifications to the copy do not affect the original? I'm sorry for misunderstanding, but if you read your original question you'll note that you used the word copies exactly once and not in any way that made much sense - the main noun was an orm object, singular, and the next paragraph referred again to an object and it. The mapped object has a member _sa_instance_state that you basically don't want to transfer to your new object.You want it to have its own _sa_instance_state and this comes from calling the plain constructor, which the copy module, if that's what you're using, does not use. You also want to set attributes normally, not populating __dict__ directly. So just basically don't use the copy module. Just construct a new object. x = MyObject(foo=myoldobject.foo, bar=myoldobject.bar). or x = MyObject() for a in dir(myoldobject): if not a.startswith('_'): setattr(x, a, getattr(myoldobject, a)) Could you perhaps repeat the answer in baby-talk language? Babies don't know how to program computers in the first place, so I'd aim higher than that. -- 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] Extending DeclarativeBase
On Aug 24, 2010, at 7:54 PM, waugust wrote: Greetings, I was playing around and trying to extend the DeclarativeBase with some Elixir like functions... I may be to green in Python itself that I'm missing something though, here's what I got... class ModelBase(DeclarativeMeta): @classmethod def get(cls, id): row = meta.Session.query(cls).filter_by(id=id).one() return row DeclarativeBase = declarative_base(metaclass=ModelBase) metadata = DeclarativeBase.metadata A metaclass is a subclass of type, and represents special behavior added to your classes' type, not the class itself. If that doesn't make much sense, this is common as metaclasses are a little hard to grasp at first, theres a decent intro at http://www.voidspace.org.uk/python/articles/metaclasses.shtml. anyway if you're just looking for classmethods that are common to all your mapped classes, use either a mixin (plenty of mixin info in the declarative docs) or specify a base class to declarative_meta using cls - the resulting class will be a subclass of the class you send. It defaults to object. uhhh... so how does the introspection work here (if any)? I'm I a bit too naive here? calling cls.__class__, cls.__table__, or cls.__call__() doesn't seem to do it... -- 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] How to delete in ORM without querying first?
In the code below I set up two users using an orm session, and then delete one of them with a second orm session. import sqlalchemy as sa from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker Base = declarative_base() class User(Base): __tablename__ = users id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String) fullname = sa.Column(sa.String) def __init__(self, name, fullname): self.name = name self.fullname = fullname import os dbEngine = sa.create_engine(sqlite://, echo = True) Base.metadata.create_all(dbEngine) Session = sessionmaker(bind = dbEngine, autoflush = True, autocommit = False) #Add some data... s1 = Session() u1 = User(fred, Fred Flintstone) u2 = User(barney, Barney Rubble) s1.add(u1) s1.add(u2) s1.commit() #delete the fred user... name_to_delete = fred s2 = Session() fred = s2.query(User).filter_by(name = name_to_delete).first() s2.delete(fred) s2.commit() In this reduced example I magically know the user name I want to delete (fred) and know that it exists. I also obviously don't need the second session in this example, but it is a reduction of my problem. The SQL query result for the second session is below: BEGIN SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname FROM users WHERE users.name = ? LIMIT 1 OFFSET 0 ('fred',) DELETE FROM users WHERE users.id = ? (1,) COMMIT The first query is wasteful for what I'm trying to achieve, which is to delete the user whose user.name I *know* is there (even if I didn't know, I'd be content to catch the exception). What I can't figure out is... with the second session, what is the correct/best way to do a simple deletion without requiring a mapped orm object to give to session.delete? Do I need to leave the orm world to do this? I would rather not resort to session.execute if at all possible. -- 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] Re: How to delete in ORM without querying first?
On Aug 25, 12:01 am, Fernando Takai fernando.ta...@gmail.com wrote: Have you tried: #delete the fred user... name_to_delete = fred s2 = Session() s2.query(User).filter_by(name = name_to_delete).delete() s2.commit() ? No I had not... :( That works absolutely perfectly, though with just enough SQL. Thanks! I clearly need to get my head wrapped more around how sqla querying works. That is not yet intuitive to me how that works inside. I likely have examples like that (doing a full SELECT prior to what I actually want to do) peppered throughout my code. -- 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.