I have seen it in the docs and that is where the solution came from. 
When not interested in a property I tend to remember it is there but not read 
into it, which is normal I guess..

I was looking at some commented out code in that bit and saw I had tried 
name='JSid' but since "name" was used in Extending SA.Column for my use. 
Interested in why I tried that I looked into the docs to find out the "First 
Property" option. This saved my ass!! as name='something' would have worked 
normally but not in this particular case….




On Mar 5, 2012, at 15:45 , Michael Bayer wrote:

> 
> On Mar 5, 2012, at 6:52 AM, Martijn Moeling wrote:
> 
>> I think I've got it working correctly.
>> 
>> 
>> in my mixin I now do:
>> 
>>     @declared_attr
>>     def id(self):
>>         return ExtColumn('JSid',Unicode(255), default = None) 
>> 
>> so the id property is actually stored in the DB Column 'JSid'
>> Since my introspection looks at the python class, it takes the name from the 
>> class definition and put's 'id' in the json.
>> 
>> the only change is 'JSid' in the definition and no extra overhead is added.
>> 
>> This is nice since whilst solving this I found out that I have a few more of 
>> these (i.e. Name and name)
>> Since I use PostgreSQL I got away with this….
> 
> 
> yeah I'm surprised you didn't know about the "attribute = 
> Column("someothername", ) calling form ?     I point it out in several places 
> in the docs, it has its own section: 
> http://docs.sqlalchemy.org/en/latest/orm/mapper_config.html#naming-columns-distinctly-from-attribute-names
>   and additionally 
> http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative.html#defining-attributes
>  .
> 
> Glad you got it working but also I will be looking into removing that lower() 
> logic by default in 0.8 since it is usually wasteful.
> 
> 
> 
>> 
>> Martijn
>> 
>> On Mar 5, 2012, at 11:55 , Martijn Moeling wrote:
>> 
>>> Michael,
>>> 
>>> Thank you for confirming my worries and adding reason to it.
>>> 
>>> I'm not sure if you remember al my questions in the past but with my 
>>> project I'm constantly hitting the "impossible", although its fun, it can 
>>> be frustrating sometimes.
>>> 
>>> What I'm doing is something bigger than just an application, I'm building 
>>> an web based operating system, with Desktop in a browser and with a 
>>> development system for applications.
>>> 
>>> It is based on Open Source products and build from absolute scratch, there 
>>> is much more to it but as I signed  a non disclosure agreement with my 
>>> self, I must stop here.
>>> 
>>> Since I Love Python and absolutely hate Javascript, HTML, CSS, I Have put a 
>>> lot of effort in doing away with those and replace them with Python, 
>>> Basically what I have is an IDE to develop web appellations which in itself 
>>> is a web application. Within that you can write Python which is "Compiled" 
>>> into all the parts needed by a browser.
>>> It resembles something which is very close to Visual Basic 6.0 if you 
>>> remember that one from a developer point of view.
>>> 
>>> Since I use the Id field for SA in the usual fashion, I struggle where I 
>>> reflect Javascript objects with an "id" field.
>>> Everything is generated with Introspection, I subclassed the SA Column to 
>>> add properties to the colums. These are non functioning in "run" mode but 
>>> are used when compiling to javascript. (the _constuctor returns the real 
>>> Column, not the extended one).
>>> 
>>> the id column is coming from Python classes generated from the sources of 
>>> ExtJs, the Id column is tightly bound to communication between browser and 
>>> back-end (Since its the recordId).
>>> 
>>> at the end the Id column will be/is hidden from the developer, but I have 
>>> tons and tons of code relying on Id.
>>> Within the IDE a user would and should be able to instance an object with 
>>> an "id" doing so in the creation is no problem since python differs between 
>>> id and Id (and Id is never set by code)
>>> 
>>> so :
>>> 
>>> id  = ExtendedSAColumn(Unicode(25), default = ….)
>>> 
>>> will end up ad {xtype : 'textfield' , id : 'the id' ……}
>>> 
>>> For "compile time" I have no Issues with overhead
>>> 
>>> I can rename id to JS_id (or something) but I need to be able to do 
>>> Someclass.id = 'the id'
>>> 
>>> and print Someclass.id (or use the value in some other way)
>>> 
>>> Since an Application and its components are reflected in the database, 
>>> almost all classes which are compiled into javascript will have an id 
>>> column. adding a @declared_attr to my mixin en a setter function and map id 
>>> to JSid adds an id column to everything and that is not what I want (and 
>>> messes with my introspection routines to reflect SA Database object classes)
>>> 
>>> I must find a way where the id field can be used in the IDE without adding 
>>> any special code there, it should be transparent to users of my system.
>>> 
>>> Thing is, on some objects (maybe most, at least the ones which have to do 
>>> with stores and models) I Introspect a Class and not an instance of that 
>>> Class. While during "runtime" these python objects are used to query the 
>>> database and converted to json to fit into the generated stores and models 
>>> (as defined by Extjs). and during runtime all "overhead" is just not there, 
>>> so translating JSid into id will be needed on each record, if it has an id 
>>> property or not.
>>> 
>>> Is there a way to use declarative and map the id property to a different 
>>> name?
>>> 
>>> 
>>> like:
>>> 
>>> id          = Column(integer, name='JSid'……)
>>> 
>>> I have something similair to this:
>>> I've left out the filtering of SA Colum arguments as I did with the 
>>> processing of NON SA column arguments to __init__
>>> 
>>> class ExtColum(Column):
>>> 
>>> def __init__(self, type, *arg ,**kwarg):
>>>     #filter out the SA Column properties into "filteredoptions" and:
>>>     Column.__init__(self, type_, *arg,**filteredoptions)
>>> 
>>> def _constructor(self, name, type_ *a, **kw):
>>>     column= Column(type,*a, **kw)
>>>     column.name = name
>>>     return column
>>> 
>>> 
>>> in the _constructor I can mess with the name:
>>> 
>>> def _constructor(self,name, type_ *a,**kw):
>>>     column= Column(type,*a, **kw)
>>>     if name == "JSid":
>>>             column.name = "id"
>>>     else:
>>>             column.name = name
>>> 
>>> I think this would fix runtime, as _constructor is called on record load 
>>> but how to set the Column name in the __init__
>>> 
>>> My introspection routines would "see" the "id" column as an ExtColumn but 
>>> would store it's value in JSid and not mess with the functionality of SA 
>>> and or the database as "jsid" would NOT interfere with Id.
>>> 
>>> Solving it this way, the overhead is only on ExtColumn based Columns which 
>>> saves a lot. Again this would be unusual use of SA for as far as I can see.
>>> 
>>> reading the docs for the Column object:
>>> The name of this column as represented in the database. This argument may 
>>> be the first positional argument, or specified via keyword.
>>> 
>>> Names which contain no upper case characters will be treated as case 
>>> insensitive names, and will not be quoted unless they are a reserved word. 
>>> Names with any number of upper case characters will be quoted and sent 
>>> exactly. Note that this behavior applies even for databases which 
>>> standardize upper case names as case insensitive such as Oracle.
>>> 
>>> The name field may be omitted at construction time and applied later, at 
>>> any time before the Column is associated with a Table. This is to support 
>>> convenient usage within the declarative extension.
>>> 
>>> 
>>> the last paragraph is the most interesting. testing however makes me unsure 
>>> where to put the name. and even more interesting, how to test for the name 
>>> in the __init__ ?
>>> 
>>> for some reason I do not seem to get no reference to name, even after 
>>> calling Column.__init__, self.name == None, Am I thinking in the wrong 
>>> direction?
>>> 
>>> 
>>> Martijn
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>>  
>>> 
>>>  
>>> 
>>> 
>>> 
>>> On Mar 5, 2012, at 00:06 , Michael Bayer wrote:
>>> 
>>>> 
>>>> On Mar 4, 2012, at 2:18 PM, Martijn Moeling wrote:
>>>> 
>>>>> sqlalchemy.exc.DataError: (DataError) invalid input syntax for integer: 
>>>>> "Blablabla"
>>>>> LINE 3: WHERE ide_applicationcontroller."Application" = E'Blablabla...
>>>>>                                                         ^
>>>>>  'SELECT ide_controller."Id" AS "ide_controller_Id", 
>>>>> ide_controller."Name" AS "ide_controller_Name", ide_controller."onLaunch" 
>>>>> AS "ide_controller_onLaunch", ide_controller.id AS ide_controller_id 
>>>>> \nFROM ide_controller, ide_applicationcontroller \nWHERE 
>>>>> ide_applicationcontroller."Application" = %(param_1)s AND 
>>>>> ide_applicationcontroller."Controller" = ide_controller."Id"' {'param_1': 
>>>>> u'Blablabla'}
>>>> 
>>>> 
>>>>> 
>>>>> 
>>>>> I do not understand where the "E" is coming from, I've check and checked 
>>>>> and never reference to "id" anywhere by mistake
>>>> 
>>>> the "E" is part of how psycopg2/libpq renders bound parameters before 
>>>> passing off to the backend, and is normal.
>>>> 
>>>> 
>>>>> 
>>>>> I can not freely choose my columnnames
>>>> 
>>>> OK well I can confirm the use case is not supported at all on SQLAlchemy - 
>>>> SQLA is case insensitive in how it deals with result set column names.  
>>>> It's been that way since the beginning and nobody has ever asked for it to 
>>>> be changed, much less even noticed it, most likely.     Had I been making 
>>>> this decision today, I would not have chosen the lower() option, as it 
>>>> adds performance overhead in any case and is for the vast majority of 
>>>> cases completely unnecessary.    However, I don't recall if I was coming 
>>>> up against DBAPIs that were not giving me the correct casing within 
>>>> cursor.description, and I'm not sure if all DBAPIs handle this correctly, 
>>>> so there is some risk to changing the behavior.
>>>> 
>>>> So I'd point out that this use case you have here is exceedingly unusual.  
>>>> Many databases don't support it, not even SQLite, which won't let me 
>>>> create such a table, even if I quote both names:
>>>> 
>>>>    duplicate column name: Id u'\nCREATE TABLE a (\n\t"id" INTEGER NOT 
>>>> NULL, \n\t"Id" INTEGER, \n\tPRIMARY KEY ("id")\n)\n\n' ()
>>>> 
>>>> nor will the current release of MySQL:
>>>> 
>>>>    (1060, "Duplicate column name 'Id'") '\nCREATE TABLE a (\n\t`id` 
>>>> INTEGER NOT NULL AUTO_INCREMENT, \n\t`Id` INTEGER, \n\tPRIMARY KEY (`id`), 
>>>> \n\tUNIQUE (`Id`)\n)\n\n' ()
>>>> 
>>>> So generally, mixing overlapping names based on case within relational 
>>>> databases is a really bad idea, and is just asking for trouble at every 
>>>> stage.  
>>>> 
>>>> 
>>>>> and do not really want to run code for every parameter just to see if 
>>>>> there is an id field and put the value in whatever other storage name, 
>>>>> that will add unwanted load to my system.
>>>> 
>>>> So if your system is truly "generic" and you can't anticipate what 
>>>> existing names are present, I'd point out that right off, your approach 
>>>> will not work for SQLite or MySQL, which will not allow such a naming 
>>>> convention in any case.
>>>> 
>>>> The logic we're talking about here would take place at configuration time 
>>>> in any case, and would be a completely minuscule check that runs just once 
>>>> per class at import time, so there's no "load" issue.    Also, what if you 
>>>> were given a class that actually had the lowercase name "id" on it 
>>>> already?  If you have no control over column names,  don't you need to 
>>>> check for that name already existing?  Or are you publishing a restriction 
>>>> that this name is "reserved", and in which case why not say that all 
>>>> casing conventions of "id" are reserved as well ?
>>>> 
>>>> 
>>>>> Is this a bug? or do I hit a Feature of SA where it does not matter if id 
>>>>> or Id is used and somewhere a .lower() takes care of that. Can I switch 
>>>>> it off if so?
>>>> 
>>>> The model for the statement compiler and result proxy works on a case 
>>>> insensitive model right now as far as how columns are located in result 
>>>> sets, I can't even get a plain row back using such a casing convention.
>>>> 
>>>> Ticket #2423 (http://www.sqlalchemy.org/trac/ticket/2423) illustrates a 
>>>> patch that would allow the behavior to be configurable.   As anticipated, 
>>>> it adds 7% method call overhead to key performance tests, when the "case 
>>>> insensitive" behavior is turned on as it doubles the function call 
>>>> overhead for each lower().   Which leads me to want to release it in 0.8 
>>>> with the default behavior reversed, thereby avoiding the double-function 
>>>> call for the vast majority of cases that aren't attempting to refer to 
>>>> columns in a case-insensitive manner.   But I'd have to do a deep sweep 
>>>> across all the DBAPIs I can find, because if any of them are lowercasing 
>>>> on their end, then the change will be incompatible - those DBAPIs might 
>>>> want to signal that the flag turns back on.
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "sqlalchemy" group.
>>>> To post to this group, send email to [email protected].
>>>> To unsubscribe from this group, send email to 
>>>> [email protected].
>>>> 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 [email protected].
>>> To unsubscribe from this group, send email to 
>>> [email protected].
>>> 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 [email protected].
>> To unsubscribe from this group, send email to 
>> [email protected].
>> 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 [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> 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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to