Re: [sqlalchemy] Multi-column primary key with autoincrement?

2009-12-16 Thread Adrian von Bidder
Heyho!

[multi-column primary key where one column is autoincrement int]

On Wednesday 16 December 2009 05.29:54 Daniel Falk wrote:
 The true problem here 
 is with sqlite, which tries to make a smart choice about whether to 
 autoincrement or not.  And it gets it wrong.  SQLAlchemy is correct to 
 not specify the id field in the INSERT statement.  That's the cue to the 
 db that it needs to supply that value on its own.

Hmm.

Closer inspection shows that 
 * sqlite doesn't even support the scenario I want (autoincrement on one 
column with multi column primary key) and
 * sqlalchemy doesn't notice this and just creates a two column primary key 
without autoincrement at all.

Is there any hope that sqlalchemy will start to simulate the feature on 
sqlite? (I'm using the python-pysqlite2 2.5.5-3 / libsqlite3-0 3.6.20-1 / 
python-sqlalchemy 0.5.6-1 packages from Debian squeeze, btw)

I've opened #1642 now.

PostgreSQL handles this in just the way I was expecting (no surprise since 
my expectation on autoincrement columns is derived from the way pg builds 
its serial data type :-), so I'll have to test if sqlalchemy will do the 
right thing here.  Then I can at least use pg (I was planning to do so in 
production anyway; sqlite is convenient for development though.)


cheers
-- vbi

-- 
featured product: GNU Privacy Guard - http://gnupg.org


signature.asc
Description: This is a digitally signed message part.


[sqlalchemy] Warning when relation on mapper supercedes the same relation on inherited mapper

2009-12-16 Thread Gunnlaugur Briem
Hi,

I created a mapper inheriting from another mapper and overriding a
relation definition, and got this warning:

Warning: relation 'dimensions' on mapper 'Mapper|DataSetSlice|
dataset_slice' supercedes the same relation on inherited mapper
'Mapper|DataSet|dataset'; this can cause dependency issues during
flush

I'd like to understand those dependency issues better (read: at all),
to know whether they apply in my case.

The new class I am mapping is class DataSetSlice(DataSet), which
defines a slice out of another DataSet (identified by parent_id, a
self-join on the dataset table), but is also a DataSet in its own
right (fitting into our inventory/categorization system). So there is
an inheritance relationship and also (separately) a parent/child
relationship.

A DataSet has dimensions (many-to-many), and a DataSetSlice logically
has the same dimensions as its parent. So the DataSet mapper has this
relation:

dataset_mapper = mapper(DataSet, dataset_table
...,
properties={
'dimensions': relation(Dimension,
secondary=dataset_dimension_association,
order_by=dataset_dimension_association.c.dimension_id,
backref='referencing_datasets'
),
})

And the DataSetSlice (subclass) mapper has this instead:

datasetslice_mapper = mapper(DataSetSlice, datasetslice_table,
...,
properties={
'dimensions': relation(Dimension,
secondary=dataset_dimension_association,
primaryjoin=dataset_dimension_association.c.dataset_id
== datasetslice_table.c.parent_id,
foreign_keys=[dataset_dimension_association.c.dataset_id,
  dataset_dimension_association.c.dimension_id
  ],
order_by=dataset_dimension_association.c.dimension_id,
backref='referencing_dataset_slices'
),
})

The salient difference is that the primary join references parent_id
in the subclass table instead of id in the superclass table --- but
these are the same by a foreign key relationship. Thus I'm making a
slice have the same dimensions as its parent.

Could someone please explain the dependency issues that can arise from
this? (Or explain generally the kind of dependency issue this warning
refers to?)

Regards,

- Gulli

--

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] Multi-column primary key with autoincrement?

2009-12-16 Thread Michael Bayer
Adrian von Bidder wrote:
 Heyho!

 [multi-column primary key where one column is autoincrement int]

 On Wednesday 16 December 2009 05.29:54 Daniel Falk wrote:
 The true problem here
 is with sqlite, which tries to make a smart choice about whether to
 autoincrement or not.  And it gets it wrong.  SQLAlchemy is correct to
 not specify the id field in the INSERT statement.  That's the cue to the
 db that it needs to supply that value on its own.

 Hmm.

 Closer inspection shows that
  * sqlite doesn't even support the scenario I want (autoincrement on one
 column with multi column primary key) and
  * sqlalchemy doesn't notice this and just creates a two column primary
 key
 without autoincrement at all.

 Is there any hope that sqlalchemy will start to simulate the feature on
 sqlite? (I'm using the python-pysqlite2 2.5.5-3 / libsqlite3-0 3.6.20-1 /
 python-sqlalchemy 0.5.6-1 packages from Debian squeeze, btw)

 I've opened #1642 now.

Sorry, I've closed it.  SQLite doesn't support autoincrement on composite
PKs and theres no one-size-fits-all way to simulate this, so its up to
the user.  You need to either use the default keyword and specify a
function or SQL expression that will generate new identifiers, or just set
up the PK attributes on your new objects before adding them to the
session.


 PostgreSQL handles this in just the way I was expecting (no surprise since
 my expectation on autoincrement columns is derived from the way pg builds
 its serial data type :-), so I'll have to test if sqlalchemy will do the
 right thing here.  Then I can at least use pg (I was planning to do so in
 production anyway; sqlite is convenient for development though.)

absolutely, PG uses sequences and has no issue here.  the
no-autoincrement-sqlite thing is an only-sqlite issue and we also have
some unit tests that specifically skip sqlite for this reason.




 cheers
 -- vbi

 --
 featured product: GNU Privacy Guard - http://gnupg.org


--

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] Warning when relation on mapper supercedes the same relation on inherited mapper

2009-12-16 Thread Michael Bayer
Gunnlaugur Briem wrote:
 Hi,

 I created a mapper inheriting from another mapper and overriding a
 relation definition, and got this warning:

 Warning: relation 'dimensions' on mapper 'Mapper|DataSetSlice|
 dataset_slice' supercedes the same relation on inherited mapper
 'Mapper|DataSet|dataset'; this can cause dependency issues during
 flush

 I'd like to understand those dependency issues better (read: at all),
 to know whether they apply in my case.

 The new class I am mapping is class DataSetSlice(DataSet), which
 defines a slice out of another DataSet (identified by parent_id, a
 self-join on the dataset table), but is also a DataSet in its own
 right (fitting into our inventory/categorization system). So there is
 an inheritance relationship and also (separately) a parent/child
 relationship.

 A DataSet has dimensions (many-to-many), and a DataSetSlice logically
 has the same dimensions as its parent. So the DataSet mapper has this
 relation:

 dataset_mapper = mapper(DataSet, dataset_table
 ...,
 properties={
 'dimensions': relation(Dimension,
 secondary=dataset_dimension_association,
 order_by=dataset_dimension_association.c.dimension_id,
 backref='referencing_datasets'
 ),
 })

 And the DataSetSlice (subclass) mapper has this instead:

 datasetslice_mapper = mapper(DataSetSlice, datasetslice_table,
 ...,
 properties={
 'dimensions': relation(Dimension,
 secondary=dataset_dimension_association,
 primaryjoin=dataset_dimension_association.c.dataset_id
 == datasetslice_table.c.parent_id,
 foreign_keys=[dataset_dimension_association.c.dataset_id,
   dataset_dimension_association.c.dimension_id
   ],
 order_by=dataset_dimension_association.c.dimension_id,
 backref='referencing_dataset_slices'
 ),
 })

 The salient difference is that the primary join references parent_id
 in the subclass table instead of id in the superclass table --- but
 these are the same by a foreign key relationship. Thus I'm making a
 slice have the same dimensions as its parent.

Just to establish what I've understood here:

- there's two tables, dataset_table and datasetslice_table.
- these two tables have *two* foreign key references to each other - an
inheritance relationship (on unknown columns since they aren't displayed
here) and another on parent_id to id, which is a one-to-many
association.
- for each row in dataset_table, a row in dataset_dimension_association
may exist.
- *however*, if a row in dataset_table also references datasetslice_table
via the inheritance relation, then there may *not* be a row in
dataset_dimension_association with that dataset_table's id - because the
mapping says that dimensions now needs to reference
dataset_dimension_association via *another* row in dataset_table which it
references via parent_id.   This is a constraint that isn't expressed in
the schema but is implied by the mapping I see.

It's that last constraint that is very awkward here and is not in the
spirit of relational databases.  It means that its impossible to create a
reasonable join from dataset_table to dataset_dimension_association, since
for some rows in dataset_table, the join is invalid.

The hypothetical issue as far as flush() is that both dimension relations
would have some interaction when working out dependencies and association
row values, even for a DataSetSlice object, and would incur conflicting
data.  I'm not sure if that is the current behavior and would have to
verify, though the warning stays in place since with inheritance, you need
to look at relations from table hierarchy A to table B in terms of the
bottommost table in the A hierarchy - relational inheritance is not really
polymorphic in that way, for the join reasons I mention above.


--

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] Multi-column primary key with autoincrement?

2009-12-16 Thread Alex Brasetvik

On Dec 16, 2009, at 09:32 , Adrian von Bidder wrote:

 sqlite is convenient for development though

Except when it *adds* complexity? ;-)

--
Alex Brasetvik

--

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] sqlite and thread

2009-12-16 Thread drakkan
Hi,

I'm using a sqlite file based database, I'm having problem making
database calls from two different thread, the error is the following:

SQLite objects created in a thread can only be used in that same
thread

here is my sa configuration:

from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import scoped_session
from sqlalchemy import create_engine
from sqlalchemy.pool import NullPool
from myapp import settings
import sqlite3

connectionstring = 'sqlite:///' + settings.DATABASE_PATH+'?
check_same_thread=False'

#engine = create_engine(connectionstring, echo=settings.DEBUG,
echo_pool=settings.DEBUG)
engine = create_engine(connectionstring, echo=settings.DEBUG,
pool=NullPool(lambda: sqlite3.connect(settings.DATABASE_PATH)))

#engine = create_engine(connectionstring, echo=True, echo_pool=True)

sess = scoped_session(sessionmaker(bind=engine))
#sess = sessionmaker(bind=engine)

as you can see I'm using check_same_thread=False, Null connection pool
and scoped session, what's wrong?

thanks
Nicola

--

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] sqlite and thread

2009-12-16 Thread Michael Bayer
drakkan wrote:
 Hi,
 connectionstring = 'sqlite:///' + settings.DATABASE_PATH+'?
 check_same_thread=False'

 #engine = create_engine(connectionstring, echo=settings.DEBUG,
 echo_pool=settings.DEBUG)
 engine = create_engine(connectionstring, echo=settings.DEBUG,

this line:

 pool=NullPool(lambda: sqlite3.connect(settings.DATABASE_PATH)))

negates the effect of the check_same_thread flag in this line since the
fully constructed pool + creation function you're sending means the URL
isn't used:

 engine = create_engine(connectionstring, echo=settings.DEBUG,

you only need pool_class=NullPool in your create_engine here.  Example
here: http://www.sqlalchemy.org/trac/wiki/DatabaseNotes#SQLite

--

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: Modify the start number of a sequence after it's been created

2009-12-16 Thread Jason R. Coombs
Here's what I do.

First, I get the sequence f rom the table's columns

seq = table.c.id.default
# or if you have a mapper-class
# seq = MyClass.id_property.property.columns[0].default

Then, I execute that sequence to advance the sequence until it's the
value needed.

engine.execute(seq)

The reason I only execute the sequence once is because in my use case,
I know I've just inserted one record manually, so I only want to
advance the sequence once.

I think in your case, after getting the sequence, I would do something
like the following:

column = table.c.id
# or if you have a mapper
# column = MyClass.id_property.property.columns[0]
seq = column.sequence
# get the max ID
maxid = session.query(func.max(column)).one()[0]
# repeatedly advance the sequence until it's greater or equal than the
maxid
while seq.execute()  maxid: pass


I don't think this is the best solution, but it's the best thing I've
come up with so far with my limited knowledge.

Good luck.

On Nov 16, 12:56 pm, Jaume Sabater jsaba...@gmail.com wrote:
 Hello everyone!

 I've been searching information regarding this topic but without help
 so far. I have a dbloader.py script that takes information from a
 number of CSV files and dumps it into the database. After that we
 execute a number of tests to check all services are working fine
 (returning the right information and calculated data such as
 availability and so on).

 In these CSV files I have manually set up the id fields of every
 table, but when I add the rows to the database, I am passing the id
 value as part of the dictionary, therefore the sequence of the primary
 key is not updated. So, after all data has been loaded, I'd like to
 update the start value of the sequence.

 It's PostgreSQL, therefore I could do something like:

 maxid = engine.execute('select max(id) from table').fetchone()[0]
 engine.execute(select setval('table_id_seq', %s) % (maxid + 1))

 But I'd like to do this properly, at SA level. Just in case database
 changes in the future or just to satisfy myself. But I have not been
 able to find the way to modify the attributes of the sequence of each
 table I find in the metadata. I have found ways of retrieving the
 nextid in the documentation, but not modifying it.

 Is there a way to grab a sequence and set it's next value using the
 abstractions SA facilitates?

 Thanks in advance.

--

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: Type of Column added with column_property

2009-12-16 Thread sandro dentella
Just to be clearer: if I used func.count, the property is correctly
set to Intege type. How can I create a column in the mapper and have
the column reflect the real type in the db.

I do introspections in columns to prepare the gui to display it and to
add filters on that field (http://sqlkit.argolinux.org/sqlkit/
filters.html) and that would help a lot.

thanks in advance
sandro
*:-)

On 15 Dic, 19:58, Alessandro Dentella san...@e-den.it wrote:
 Hi,

 is there a way to set the type of a column added to a mapper with
 column_property?

   m = mapper(New, t, properties={
'my_bool': column_property(
func.my_bool(t.c.id, type=Boolean)
   )
 })

 func 'my_bool' is a stored procedure on Postgresql and returns a boolean, but
 the type of the column is NullType:

   m.get_property('my_bool').columns[0].type
   NullType()

 --
 Sandro Dentella  *:-)http://sqlkit.argolinux.org   SQLkit 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.




Re: [sqlalchemy] Re: Type of Column added with column_property

2009-12-16 Thread Michael Bayer
sandro dentella wrote:
 Just to be clearer: if I used func.count, the property is correctly
 set to Intege type. How can I create a column in the mapper and have
 the column reflect the real type in the db.

 I do introspections in columns to prepare the gui to display it and to
 add filters on that field (http://sqlkit.argolinux.org/sqlkit/
 filters.html) and that would help a lot.

 thanks in advance
 sandro
 *:-)

 On 15 Dic, 19:58, Alessandro Dentella san...@e-den.it wrote:
 Hi,

 is there a way to set the type of a column added to a mapper with
 column_property?

   m = mapper(New, t, properties={
'my_bool': column_property(
func.my_bool(t.c.id, type=Boolean)
   )
 })

 func 'my_bool' is a stored procedure on Postgresql and returns a
 boolean, but
 the type of the column is NullType:

you mean to say type_=Boolean.




   m.get_property('my_bool').columns[0].type
   NullType()

 --
 Sandro Dentella  *:-)http://sqlkit.argolinux.org   SQLkit 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.




--

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] Multi-column primary key with autoincrement?

2009-12-16 Thread Adrian von Bidder
Heyho!

On Wednesday 16 December 2009 16:36:10 Michael Bayer wrote:
 You need to either use the default keyword and specify a
 function or SQL expression that will generate new identifiers, or just set
 up the PK attributes on your new objects before adding them to the
 session.

... or just switch to pg for testing.  I don't care to support other db 
anyway.

Ok, thanks for clearing this up.

cheers
-- vbi


-- 
If we can capitalize on something that did or did not happen in 1947
then it can help the entire state.
-- Rep. Dan Foley on inventing the Extraterrestrial Culture Day


signature.asc
Description: This is a digitally signed message part.


[sqlalchemy] Re: performance issues

2009-12-16 Thread Antoine Pitrou
Hello,

 just in case you're not motivated to share mappings here, I would note that 
 an incorrect placement of a
 flag like remote_side on a relation() may be causing this.

I would have to produce anonymized mappings, but I will do so if it's
useful. What do you mean by incorrect placement of a flag like
`remote_side`? I do have one (exactly one) relation with a
`remote_side` flag, but the class it is defined on isn't involved in
the script I have timed here. (it is on a recursive relation)

 yet another thought, which again reveals how much easier this would be with 
 some sample code -
 if you're in a loop that is calling query(), then changing things, then 
 around again, you may have
 excessive triggering of autoflush going on, which also can result in lots of 
 _save_obj() calls.    Set the
 autoflush flag on your Session to be false, which you can do temporarily 
 within a particular section or
 across the whole session.    Calling commit() will issue a flush(), or 
 alternatively you can call flush() every
 few thousand new records.

Ah, a very useful tip. Setting autoflush to False does speed up things
quite a bit (a sample run of the script is 2x faster).
I haven't found how to enable it temporarily, though. I'm using a
ScopedSession instance and if I call `db_session.configure
(autoflush=False)`, or set the autoflush attribute, autoflushing still
happens. An example:

 db_session
sqlalchemy.orm.scoping.ScopedSession object at 0x2e467d0
 db_session.autoflush = False
 lg = db_session.query(Logement)[0]
[ SNIP long SELECT ]
 lg.tel1 = abc
 db_session.query(Zone)[0]
2009-12-17 00:11:35,161 INFO sqlalchemy.engine.base.Engine.0x...c550
UPDATE logement SET date_modif=%s, tel1=%s WHERE logement.id_logement
= %s
2009-12-17 00:11:35,162 INFO sqlalchemy.engine.base.Engine.0x...c550
[datetime.datetime(2009, 12, 17, 0, 11, 35, 161436), 'abc', 4L]
2009-12-17 00:11:35,167 INFO sqlalchemy.engine.base.Engine.0x...c550
SELECT zone.id_zone AS zone_id_zone, zone.cp AS zone_cp
FROM zone
 LIMIT 0, 1
2009-12-17 00:11:35,168 INFO sqlalchemy.engine.base.Engine.0x...c550
[]
xxx.Zone object at 0x3309150


(as you see, an UPDATE is issued before the SELECT for the query)

Regards

Antoine.

--

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: performance issues

2009-12-16 Thread Michael Bayer
Antoine Pitrou wrote:
 Hello,

 just in case you're not motivated to share mappings here, I would note
 that an incorrect placement of a
 flag like remote_side on a relation() may be causing this.

 I would have to produce anonymized mappings, but I will do so if it's
 useful. What do you mean by incorrect placement of a flag like
 `remote_side`? I do have one (exactly one) relation with a
 `remote_side` flag, but the class it is defined on isn't involved in
 the script I have timed here. (it is on a recursive relation)

if its backwards versus a backref that is also present, it can create an
overly complex dependency chain.


 yet another thought, which again reveals how much easier this would be
 with some sample code -
 if you're in a loop that is calling query(), then changing things, then
 around again, you may have
 excessive triggering of autoflush going on, which also can result in
 lots of _save_obj() calls.    Set the
 autoflush flag on your Session to be false, which you can do
 temporarily within a particular section or
 across the whole session.    Calling commit() will issue a flush(), or
 alternatively you can call flush() every
 few thousand new records.

 Ah, a very useful tip. Setting autoflush to False does speed up things
 quite a bit (a sample run of the script is 2x faster).
 I haven't found how to enable it temporarily, though. I'm using a
 ScopedSession instance and if I call `db_session.configure
 (autoflush=False)`, or set the autoflush attribute, autoflushing still
 happens. An example:

the configure only takes effect for the next session created.  so if you
said Session.remove(); Session.configure(); Session(), that would do it.

Easier for this is to hit the flag directly:

Session().autoflush = False




 db_session
 sqlalchemy.orm.scoping.ScopedSession object at 0x2e467d0
 db_session.autoflush = False
 lg = db_session.query(Logement)[0]
 [ SNIP long SELECT ]
 lg.tel1 = abc
 db_session.query(Zone)[0]
 2009-12-17 00:11:35,161 INFO sqlalchemy.engine.base.Engine.0x...c550
 UPDATE logement SET date_modif=%s, tel1=%s WHERE logement.id_logement
 = %s
 2009-12-17 00:11:35,162 INFO sqlalchemy.engine.base.Engine.0x...c550
 [datetime.datetime(2009, 12, 17, 0, 11, 35, 161436), 'abc', 4L]
 2009-12-17 00:11:35,167 INFO sqlalchemy.engine.base.Engine.0x...c550
 SELECT zone.id_zone AS zone_id_zone, zone.cp AS zone_cp
 FROM zone
  LIMIT 0, 1
 2009-12-17 00:11:35,168 INFO sqlalchemy.engine.base.Engine.0x...c550
 []
 xxx.Zone object at 0x3309150


 (as you see, an UPDATE is issued before the SELECT for the query)

 Regards

 Antoine.

 --

 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] Re: performance issues

2009-12-16 Thread Antoine Pitrou

  I would have to produce anonymized mappings, but I will do so if it's
  What do you mean by incorrect placement of a flag like
  `remote_side`? I do have one (exactly one) relation with a
  `remote_side` flag, but the class it is defined on isn't involved in
  the script I have timed here. (it is on a recursive relation)
 
 if its backwards versus a backref that is also present, it can create an
 overly complex dependency chain.

I'm not sure I understand. Does it also apply when the backref is
created implicitly, as follows:

class OT(DeclarativeBase):
[ snip ]
id_ot = Column(Integer, autoincrement=True, primary_key=True)
id_parent = Column(Integer,
   ForeignKey('ot.id_ot', use_alter=True, 
name='fk_ot_parent'))

OT.parent = relation(OT, remote_side=[OT.id_ot],
 backref=backref('children'))

 the configure only takes effect for the next session created.  so if you
 said Session.remove(); Session.configure(); Session(), that would do it.

Ok, thank you.

Regards

Antoine.


--

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: Warning when relation on mapper supercedes the same relation on inherited mapper

2009-12-16 Thread Gunnlaugur Briem
On Dec 16, 4:08 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 - there's two tables, dataset_table and datasetslice_table.
 - these two tables have *two* foreign key references to each other - an
 inheritance relationship (on unknown columns since they aren't displayed
 here) and another on parent_id to id, which is a one-to-many
 association.

Yes, sorry I was unclear. The inheritance is simple joined-table
inheritance, on columns named id in both tables, the subclass id being
a foreign key referencing the superclass id. There is a discriminator
column type in the dataset table with the value 'slice' for
DataSetSlice datasets, and 'base' for the regular ones.

 - for each row in dataset_table, a row in dataset_dimension_association
 may exist.
 - *however*, if a row in dataset_table also references datasetslice_table
 via the inheritance relation, then there may *not* be a row in
 dataset_dimension_association with that dataset_table's id - because the
 mapping says that dimensions now needs to reference
 dataset_dimension_association via *another* row in dataset_table which it
 references via parent_id.   This is a constraint that isn't expressed in
 the schema but is implied by the mapping I see.

Yes --- or rather if there *is* such a row, it is ignored (on the
dataset side, while the backref property on the dimension will still
contain the dataset) because the dataset_table row has type='slice'.
But you're right (of course), this is bad relational design because of
the join inconsistency and the asymmetry in the many-to-many relation.

 The hypothetical issue as far as flush() is that both dimension relations
 would have some interaction when working out dependencies and association
 row values, even for a DataSetSlice object, and would incur conflicting
 data.  I'm not sure if that is the current behavior and would have to
 verify, though the warning stays in place since with inheritance, you need
 to look at relations from table hierarchy A to table B in terms of the
 bottommost table in the A hierarchy - relational inheritance is not really
 polymorphic in that way, for the join reasons I mention above.

Very true. Thanks heaps for putting that warning in the code; I would
have made do with that flawed design if you hadn't.

This was driven by the desire to (a) let slices be datasets in their
own right (fitting them naturally into our system's inventory,
category hierarchy, browsing UI, etc.) and (b) avoid the duplication
of explicitly associating each of the slices with the same set of
dimensions as its parent dataset. So I wanted to override the
dimensions property in the DataSetSlice subclass, delegating to the
parent dataset (the OO way), but that property was injected by the
mapper, so I strayed down the path of overriding it there.

I could consider this dimensions property the “raw dimensions” (maybe
rename it as such) and define a separate (non-ORM) property for the
“dimensions to use”, delegating to self.dimensions in DataSet and to
self.parent.dimensions in DataSetSlice. But then still (a) dimension
associations for a type='slice' dataset do not make sense and should
be constrained not to exist, and (b) querying for datasets having a
given dimension will only find non-slice datasets (though an outer-
join would draw in the slices). So the relational design flaw is still
there.

Instead I will probably just add the duplicate dimension associations,
a lesser evil. Additions/removals of dimensions of existing datasets
will probably not be common anyway. And possibly there will be reason
to let slice dimensions differ from parent dataset dimensions later
on. (A dataset sliced to just one value of a given dimension could be
considered not to have that dimension, for instance.)

Thank you for your characteristically helpful response! (And for all
the work you put into SQLAlchemy in general, and into supporting its
users.)

Regards,

- Gulli

--

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] lazy instrumented attributes and pickle

2009-12-16 Thread avdd
I use pickle to serialise unsaved objects in a user session.  Normally
this works fine, except that for development I use an auto-reloading
server, and pickling some objects is hitting a case where some lazy
attribute isn't fully compiled.

...
File '/home/avdd/work/careflight/src/intranet.ops2/carenet/lib/
python2.5/site-packages/sqlalchemy/orm/collections.py', line 607 in
__getstate__
  return {'key': self.attr.key,
AttributeError: 'NoneType' object has no attribute 'key'

This is when using an ordering_list.

I would have assumed that calling orm.compile_mappers() is enough to
prevent this problem, but that is not so.

Is there some hook that I can call when my application is fully
initialised to ensure that all attributes are fully instrumented and
avoid this pickling problem?  Or can I just do a sweep of all my
mapper attributes at startup?

While the problem is nothing more than an inconvenience for me, I
intend to make heavy use of pickled objects for draft object storage
and don't want my users losing data across system restarts.

a.

--

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.