[sqlalchemy] Filtering for element in PgArray column

2012-08-13 Thread Vlad K.


Hi all,


what is the proper way to filter for element in a PostgreSQL ARRAY 
column? in_() does not produce valid syntax for PostgreSQL (  does 
(value) instead of array[value] ).


For now I'm doing the following, but I'm not sure how to bind values and 
not have such a gaping sql injection vuln (even though somevalue is 
checked against a list of allowed (unicode) values, I want proper binding:



rows = session.query(Model).filter(text({0} @ 
{1}.format(Model.__table__.c.array_column, 'somevalue').all()



Which should produce:


SELECT * FROM model_table WHERE array_column @ ARRAY['somevalue']


--


.oO V Oo.


Work Hard,
Increase Production,
Prevent Accidents,
and
Be Happy!  ;)

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] PostgreSQL hstore support for SQLAlchemy

2012-08-13 Thread Michael Bayer
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1


On Aug 11, 2012, at 3:18 PM, Audrius Kažukauskas wrote:

 Hi,
 
 I've been looking for a way to use PostgreSQL's hstore type in SA, and
 from all the options that I have found on the net the one written by
 Kyle Schaffrick (big thanks to him) and posted in this list[0] was the
 most promising.
 
 [0] 
 https://groups.google.com/forum/?fromgroups#!topic/sqlalchemy/IgdaTHHgQi0%5B1-25%5D
 
 So I took it and added some missing bits.  The result can be found at
 https://bitbucket.org/audriusk/hstore.  Apart from a couple of issues
 (and lacking proper tests), I feel that it's quite usable now.  Here's
 the more detailed list of what's been changed:
 
 - As was suggested by Mike Bayer in the aforementioned thread, switched
  from MutableType to sqlalchemy.ext.mutable.
 - Removed usage of string_encode.  In my tests it wasn't working as
  expected, Postgres was storing literals like '\x42' as 'x42'.  As a
  result, now unicode strings are accepted as well.
 - Added NULL support for values and got rid of unquoted keys and values
  part in parser regexp (only NULL value is unquoted).
 - Fixed regexp to work with values which contain escaped quotes.
 - Changed pair() to return 'hstore(key, value)' instead of 'key =
  value' (according to PostgreSQL docs, the latter is deprecated).
 - HStoreColumn doesn't require HStore type as an argument anymore.
 - Used comparator, without it hstore specific methods were inaccessible
  from mapped classes.  Also added HStoreColumnProp (borrowed the idea
  from GeoAlchemy).
 - Moved hstore operators and functions into HStoreMethods mixin class
  which is used by HStoreElement and HStoreComparator.
 
 The aforementioned issue is that __getitem__ and contains() do not work
 from comparator, the first one probably due to different way it's being
 accessed, the latter is shadowed by the method from some other class.
 Would be great to make at least contains() to work, if anybody has any
 ideas, please tell.
 
 This is the first time I dived deeper into SA, so the resulting code may
 use stuff improperly.  Comments, suggestions, fixes are welcome!

very nice job understanding quite a number of SQLAlchemy APIs, this is good 
work.   It reminds me also of how we still have a weakness in the Core API, 
that we can't add new comparison methods at the Core level onto Column objects 
and such.   The column_property() here is a well-designed workaround for that.

Ideally MutationDict would be part of SQLAlchemy,  from the mutable extension.  
 the extension should have mutable versions of basic types list, dict, set.   
 That's a TODO and also we'd need lots of tests.

The contains()  method is addressed by allowing the escape argument through:

- --- a/hstore.py   Sat Aug 11 19:17:46 2012 +0300
+++ b/hstore.py Mon Aug 13 10:58:07 2012 -0400
@@ -188,7 +188,7 @@
 
 return self.op('?')(other)
 
- -def contains(self, other):
+def contains(self, other, **kw):
 Boolean expression.  Test if keys are a superset of the keys of
 the argument hstore expression.
 


as for __getitem__ I don't want to expose that as a potential operator right 
now, I'd rather look into a deeper change to the operator system first so that 
hacks like _HStoreBinaryExpression aren't needed, then we can figure out if 
there's a space for __getitem__ types of things.










 
 And Kyle, if you're reading this, it would be really nice if you noted
 under which license your initial code was published.
 
 -- 
 Audrius Kažukauskas
 http://neutrino.lt/

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.12 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQEcBAEBAgAGBQJQKRZvAAoJEDMCOcHE2v7hxO0H/0PhmViuP2ndpPCvxmtLEgx4
PFuyl7avGwOh0+64HQl1YENFtNG8ZGDINU7EilsO5HsGVTYqlbT1YsX1ecQV1ury
vLCnf6EYWAczpYa2pTgpn2mNj4WzymoFNx7uMqsoysc6nZCp2BwhMxJTEkHV5BpC
ukTDWJ4iKXCAfISDY8QaR0Ani7IjcYHN5h2Ig8v4EH9DYrocE3E6Hd87kW4N9R+N
P9zJ5/xCZBlUIxpfUsb4R8Kicv+IC+S4WAcs6oIqAllwdFTiZ/PEbRNfXuhSP4CD
zyaSUVEPeGLQDTKky86GhmA3efTjC/CH2/MeAdqaQbMYmDU7gZZiQFulwftrSms=
=1pfk
-END PGP SIGNATURE-

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] is there a reason why lower() isn't a column operation ?

2012-08-13 Thread Jonathan Vanasco
just wondering why i have to do :
sqlalchemy.sql.func.lower( class.column ) == string.lower()

instead of :
class.column.lower() = string.lower()

btw - i know in the archives people have mentioned doing an ilike
search, but a WHERE lower(column) = 'string' search will search
against a functioned index on postgres and I believe oracle.
considerably faster on large data sets.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] is there a reason why lower() isn't a column operation ?

2012-08-13 Thread Michael Bayer

On Aug 13, 2012, at 1:44 PM, Jonathan Vanasco wrote:

 just wondering why i have to do :
sqlalchemy.sql.func.lower( class.column ) == string.lower()
 
 instead of :
class.column.lower() = string.lower()
 
 btw - i know in the archives people have mentioned doing an ilike
 search, but a WHERE lower(column) = 'string' search will search
 against a functioned index on postgres and I believe oracle.
 considerably faster on large data sets.


There's hundreds of SQL functions that accept a single expression as an 
argument.  SQLAlchemy's func system is designed so that in the vast majority 
of cases, these functions aren't explicit in SQLAlchemy itself, func.NAME 
just makes a new Function object with the name NAME.

So promoting some subset of those functions to be directly present would 
require a clear rationale as to why those SQL functions need to be present on 
the Column.  Since they certainly can't all be.   Also adding two ways to do 
the same thing needs a really good reason.

The particular lower() comparison you have there isn't necessarily very 
generic.   Depending on the collation behavior of the database, it may not be 
necessary, or may not be enough to produce a faithful comparison if multibyte 
characters are in play.For example, comparing unicode strings on MySQL 
(http://dev.mysql.com/doc/refman/5.0/en/charset-collate.html) might look like:

_latin1 'Müller' COLLATE latin1_german2_ci = k

that's a lot more involved than a simple lower() call.  The real use case 
you're looking for here is case insensitive comparison, perhaps an operator 
which just does case insensitive compare at once would be easier to use, and 
also easier to augment with custom behavior.

So there's a lot of questions to be asked about this use case, all of which is 
in light of that it is 100 times harder to remove a poorly considered feature 
than to add it.

As a total coincidence, I'm working on an extensible operator system for core 
right now.  A user-defined case insensitive compare operation would be easy 
to define in this new system (and actually you could define one using 
comparator_factory at the ORM level right now anyway).   So a comparison such 
as the above, which might have edge cases that can't be met generically, might 
be better approached as a user-applied recipe.That way you get the ease of 
use and full capability, without adding incomplete features to SQLA directly. 






-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Filtering for element in PgArray column

2012-08-13 Thread Michael Bayer
we don't currently have native support for ARRAY operations and there is some 
infrastructure work that should make it easier in 0.8 to add.

for now, when you need custom operators use op():

Model.array_column.op(@)(somevalue)


On Aug 13, 2012, at 10:10 AM, Vlad K. wrote:

 
 Hi all,
 
 
 what is the proper way to filter for element in a PostgreSQL ARRAY column? 
 in_() does not produce valid syntax for PostgreSQL (  does (value) instead of 
 array[value] ).
 
 For now I'm doing the following, but I'm not sure how to bind values and not 
 have such a gaping sql injection vuln (even though somevalue is checked 
 against a list of allowed (unicode) values, I want proper binding:
 
 
 rows = session.query(Model).filter(text({0} @ 
 {1}.format(Model.__table__.c.array_column, 'somevalue').all()
 
 
 Which should produce:
 
 
 SELECT * FROM model_table WHERE array_column @ ARRAY['somevalue']
 
 
 -- 
 
 
 .oO V Oo.
 
 
 Work Hard,
 Increase Production,
 Prevent Accidents,
 and
 Be Happy!  ;)
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 To unsubscribe from this group, send email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/sqlalchemy?hl=en.
 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] how to get into PG database, is the url the right way? newbie question

2012-08-13 Thread Gery

Hello, I'm new around here and I've been using SQLalchemy (SA) for a while. 
I work with PostGis (PG), OpenLayers (OL), ExtJS, GeoExtJS and now with the 
great SA and GeoAlchemy. I have one problem, I created a model where I 
defined one table of my PG database, it has a url like this: url = 
'postgresql://postgres:password@localhost:5432/pgdb'. In my HTML, I have 
some maps displayed with OL and a toolbar built with ExtJS and GeoExtJS. I 
put a search button there using ExtJS, and the OL protocol code to get the 
data. This protocol has an url option, in this way:

 var searchformPanel = new Ext.form.FormPanel(
{
width: 250,
bodyStyle: 'padding:5px',
labelAlign: 'top',
defaults:
{
anchor: '100%'
},
protocol: new OpenLayers.Protocol.HTTP(
{
url: 'http://localhost/mop/py/dbmodel.py',
format: new OpenLayers.Format.GeoJSON()
}
),
items:
etc,etc..

my problem is that in this url I wrote the whole path where my model script 
is located, but after pressing the button I got nothing. I think I need 
something else rather than only pointing the whole path and the python 
script in the url mentioned above, is that correct? I've searched how to 
connect sqlalchemy to extjs in google but didn't find any that solved this 
doubt.

Any support is very welcome, thanks in advance.

Best regards,

Gery

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/7GJay8SzKUUJ.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Getting maximum recursion depth exception when creating a model instance with two foreign keys

2012-08-13 Thread Zhe Wu
Gotcha. Thanks!

On Monday, August 13, 2012 4:57:29 AM UTC+8, Audrius Kažukauskas wrote:

 On Sun, 2012-08-12 at 11:07:18 -0700, Zhe Wu wrote: 
  def __init__(self, body, author, story): 

 Here arguments are body, author, story. 

  comment = Comment(author, story, body) 

 And here they are author, story, body.  I believe that's the source of 
 your problem. 

 -- 
 Audrius Kažukauskas 
 http://neutrino.lt/ 


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/u3XtrS0FeGEJ.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Filtering for element in PgArray column

2012-08-13 Thread Vlad K.

On 08/13/2012 08:53 PM, Michael Bayer wrote:

we don't currently have native support for ARRAY operations and there is some 
infrastructure work that should make it easier in 0.8 to add.

for now, when you need custom operators use op():

Model.array_column.op(@)(somevalue)


I tried that, but that doesn't work because the second operand has to be 
wrapped in ARRAY[], afaik that's the only way to lookup a value in an 
array column (which is also gist indexable).



 If I  do

Model.array_column.op(@)('ARRAY[123]')

I get

SELECT * FROM model_table WHERE array_column @ 'ARRAY[123]'


and I need ARRAY[123] without quotes.

--


.oO V Oo.


Work Hard,
Increase Production,
Prevent Accidents,
and
Be Happy!  ;)

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] PostgreSQL hstore support for SQLAlchemy

2012-08-13 Thread Audrius Kažukauskas
On Mon, 2012-08-13 at 10:59:59 -0400, Michael Bayer wrote:
 very nice job understanding quite a number of SQLAlchemy APIs, this is
 good work.   It reminds me also of how we still have a weakness in the
 Core API, that we can't add new comparison methods at the Core level
 onto Column objects and such.   The column_property() here is a
 well-designed workaround for that.
 
 Ideally MutationDict would be part of SQLAlchemy,  from the mutable
 extension.   the extension should have mutable versions of basic
 types list, dict, set.That's a TODO and also we'd need lots of
 tests.

Sounds really great (especially the ability to add comparison methods
onto Column), looking forward to it.

 The contains()  method is addressed by allowing the escape argument
 through:

Thanks, I pushed the fix.

 as for __getitem__ I don't want to expose that as a potential operator
 right now, I'd rather look into a deeper change to the operator system
 first so that hacks like _HStoreBinaryExpression aren't needed, then
 we can figure out if there's a space for __getitem__ types of things.

I decided to remove it for now, as there's get() method which works in
all cases (albeit looks not as nice as using __getitem__), and I would
like to keep the symmetry between Core and ORM methods.  Will add it
back in the future, if (when) support for it comes.

Thanks for your comments!

-- 
Audrius Kažukauskas
http://neutrino.lt/


pgp8JwLxlfE5e.pgp
Description: PGP signature


Re: [sqlalchemy] Filtering for element in PgArray column

2012-08-13 Thread Michael Bayer

On Aug 13, 2012, at 3:25 PM, Vlad K. wrote:

 On 08/13/2012 08:53 PM, Michael Bayer wrote:
 we don't currently have native support for ARRAY operations and there is 
 some infrastructure work that should make it easier in 0.8 to add.
 
 for now, when you need custom operators use op():
 
 Model.array_column.op(@)(somevalue)
 
 I tried that, but that doesn't work because the second operand has to be 
 wrapped in ARRAY[], afaik that's the only way to lookup a value in an array 
 column (which is also gist indexable).
 
 
 If I  do
 
 Model.array_column.op(@)('ARRAY[123]')
 
 I get
 
 SELECT * FROM model_table WHERE array_column @ 'ARRAY[123]'
 
 
 and I need ARRAY[123] without quotes.

we can keep turning the crank here, here's a full series of examples to make 
this happen:

# step 1.   build a custom element to do the ARRAY[xyz] part of this.
from sqlalchemy.ext.compiler import compiles

from sqlalchemy.sql import ColumnElement
from sqlalchemy.sql.expression import _literal_as_binds
from sqlalchemy.dialects.postgresql import ARRAY

class MyArray(ColumnElement):
type = ARRAY
def __init__(self, expr):
self.expr = _literal_as_binds(expr)

@compiles(MyArray)
def compile(element, compiler, **kw):
return ARRAY[%s] % compiler.process(element.expr)

# step 2.  illustrate raw usage of MyArray with the ORM.
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String

Base = declarative_base()

class MyClass(Base):
__tablename__ = 'foo'
id = Column(Integer, primary_key=True)
arrvalue = Column(ARRAY(String))

print MyClass.arrvalue.op(@)(MyArray(123))

# step 3.   use ColumnProperty to define a comparator at the
# ORM level.

from sqlalchemy.orm.properties import ColumnProperty
class MyComparator(ColumnProperty.Comparator):
def array_in(self, other):
return self.__clause_element__().op(@)(MyArray(other))

class MyOtherClass(Base):
__tablename__ = 'bar'
id = Column(Integer, primary_key=True)
arrvalue = ColumnProperty(Column(ARRAY(String)), 
comparator_factory=MyComparator)

print MyOtherClass.arrvalue.array_in(123)

# step 4.  0.8 will have a core method for the comparison part which is 
easier.


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.