On Mon, Apr 13, 2009 at 7:04 PM, Yarko Tymciurak <[email protected]> wrote:
> On Mon, Apr 13, 2009 at 5:28 PM, mdipierro <[email protected]>wrote: > >> >> I can see lots of typos in people trying to do >> >> db.define_table('name','name string','birthdaty datetime') > > > Well - if the main goal is to have people type less, then this is not a > problem - can do this from an application / user interface; > > If this is a way to store a table definition on GAE, then this doesn't > matter; > > If this is a way to allow people to write programs (easily) to define new > tables (think of an issue tracking system, for example, where you can create > a tracked project, and describe custom tables) then this (multiple strings > vs. one string) is probably a better solution. > > In any case, I'm not arguing for what you want - but your arguments are > "all over the place" - people typing; GAE storing.... > > I am arguing that all of these are possible, and have an appropriate place > - and that the CORE (gluon) level should be to handle PROGRAMMATIC INPUT > which is easily derived from user input (thru a controller), or easily > coalesced into whatever you may want for GAE storage of table meta-data. > > I think that is what is at issue here - one of abstraction level, and which > is the right place to put what. > If you add all the "kinds of things" --- GAE, user easy typing, programmatic table generation - the one thing they all have in common is: some text notation to describe a field. (Also, all the kinds of applications / use cases you haven't thought of yet would have this in common). It is this common factor that belongs being handled in gluon.sql - not application / use-case level stuff. That's what I am saying. > >> vs >> >> db.define_table('name: name string, birthdaty datetime') >> >> I think we can support both notations. What do you think? > > > See my comments above. If you support both at the GLUON level, then I > argue you will have code bloat, and one piece that will be used by .... you? > classroom? people on the list who will ask you to make modifications, > instead of writing controllers / user interfaces / logic themselves? ..... > in other words, I think it's possibly but now how I would do it. > ..._not_ how I would do it. And more, I suggest (rather strongly) against the way you are proposing because I think it will reduce (rather than increase) uses, reliability, etc. > This comment: >> >> > for table in db(db.meta.id>0).select(): >> > db.define_table(table.shorthand()) >> >> I did not understand. table here is a record and table.shorthand would >> be a string value. > > > Correct - and my point was --- what do you care if > Maybe it would be clearer to you if I said, for this application you put forth, what do you care if you have: - db.define_table(table.shorthand_string) # where gluon.define_table calls yet something else to parse, which application writer cannot .... CANNOT ever modify or change (e.g. result is something overspecified by web2py!!!!) or: - db.define_table(parse( table.shorthand_string)) # you can provide default parser at app level; I can write my own, but point is: gluon.define_table only deals with the common denominator: a token pattern for describing one field, and no more. That is well defined, easily extended by web2py, and leaves appropriate flexibility at application level. - Yarko. > > - you provide a string, which then a gluon-level ("don't ever change > because of backward compatibility!!!") function will parse (and this will > be brittle, because you cannot change or add without all the "usual" > concerns, so why do this at all?) > - or you provide a "standard" contributed function which at application > level will parse > > In other words, the only thing that belongs in gluon.sql parser is for > single field definitions - write a grammer to handle that, and that's the > appropriate level for gluon. > > Anything else YOU want (eg. one strting) can be processed at application > level to easily give the gluon functions the basic tokens. > > This also leaves the door open to other kinds of uses which are the same > KIND of thing - like programmatic generation of table descriptors, user > interfaces for users to define tables, etc. > > This is the better approach. (This is my strong argument). > > Make sense? > > Regards, > Yarko > >> >> >> Massimo >> >> On Apr 13, 3:49 pm, Yarko Tymciurak <[email protected]> wrote: >> > On Mon, Apr 13, 2009 at 2:11 PM, mdipierro <[email protected]> >> wrote: >> > >> > > I agree that the syntax you propose is cleaner but why are we doing >> > > this? >> > >> > > For me the reason is move functionality out of T3. >> > >> > Ok. >> > >> > > In particular we need a way to store a model in another model (think >> > > of a table of table descriptions) in order to be able to create models >> > > on GAE without going through the local development environment. The >> > > shorthand notation for me is just a bonus. >> > >> > > Having the entire table represented as a single string accomplishes >> > > this: >> > >> > > for table in db(db.meta.id>0).select(): db.define_table >> > > (table.shorthand) >> > >> > Ok - but you are still talking higher level functionality here (single >> > string); >> > What do you loose from this: >> > >> > for table in db(db.meta.id>0).select(): >> > db.define_table(table.shorthand()) >> > >> > Nothing - it's just a matter of how much you push down into the core. >> > Putting _too_ much higher level assumptions low just blocks other, >> similar >> > (or unanticipated) uses. >> > >> > ['table_name', 'field_name:field_type:field default'] ==> "table_name; >> > field_name:field_type:field default;" >> > >> > Put another way, you are pushing a particular persistent storage issue >> down >> > into gluon (wanting a single string) - I question this. >> > >> > There are numerous ways to store, so being explicit about what _kinds_ >> of >> > uses you are targetting is important. You have stated one (and until >> now, >> > at least on this thread and in the code, it has been implicit; it's >> good to >> > make it explicit). >> > >> > In any case, if you intend to write a single blob, it would be good >> exercise >> > to implement a parser, and then think about where each piece belongs. >> (this >> > actually looked interesting, as I scanned for parser generators: >> http://www.acooke.org/lepl/) <http://www.acooke.org/lepl/> >> > >> > >> > >> > > Massimo >> > >> > > On Apr 13, 1:59 pm, Yarko Tymciurak <[email protected]> wrote: >> > > > On Mon, Apr 13, 2009 at 1:53 PM, Yarko Tymciurak <[email protected] >> > >> > > wrote: >> > > > > On Mon, Apr 13, 2009 at 1:40 PM, Yarko Tymciurak < >> [email protected] >> > > >wrote: >> > >> > > > >> I have a couple of immediate comments: >> > > > >> [1] - with this syntax, you do not process and fields or migrate >> > > > >> statements (but you _could_; suggest you do) >> > > > >> [2] - the autofields() function seems to mash concerns in other >> ways >> > > also: >> > > > >> it handles tablename update (? why here) in addition to >> "autofields"; >> > > for >> > > > >> one thing, it does NOT do cleanup() (as define_table otherwise >> does) - >> > > this >> > > > >> is the beginnings of handling things differently in different >> > > conditions >> > > > >> (and a typical symptom of blurred boundaries of concerns). >> > >> > > > >> Suggest you DO table name handling in _one place_, and field >> > > processing >> > > > >> (as you have) in one place, and consider that you only ADD >> > > "autofields" as a >> > > > >> new syntax for defining fields. >> > >> > > > >> Having said that, it occurs to me that a comma separated text >> string >> > > is >> > > > >> just one layer of this, and it would be good to split this out, >> so >> > > that >> > > > >> web2py application developers could create things more >> automatically, >> > > to >> > > > >> wit: >> > >> > > > >> [3] in sql.autofields() ==> for field in fields.split(',') ---- I >> > > would >> > > > >> make this do NO MORE than call an individual field processing >> function >> > > > >> (separate this functionality) >> > >> > > > >> [4] I would add / allow a list to be passed (that is, allow the >> > > > >> application developer to _already_ have split the field >> definitions to >> > > "the >> > > > >> new text specification format") --- this will be much handier for >> > > automated >> > > > >> processing. There are a couple of ways you could handle this, >> one >> > > being >> > > > >> parsing *fields in define_table() to first split them out to >> string >> > > (or >> > > > >> list?) vs. function types, process all the string types by some >> > > > >> autofields_parse() function, collect and pass the rest to >> > > SQLTable(self, >> > > > >> tablename, *fields)... >> > >> > > > > ... as I think of this, and of application developers I would ONLY >> > > process >> > > > > lists for the "new" syntax - there is no useful reason to have a >> string >> > > that >> > > > > the CORE then splits on ',' and only complicates the core.... >> this is >> > > the >> > > > > kind of niceity that better belongs at the application level - >> either >> > > for >> > > > > the app writer, or in an admin (or other higher level function). >> > >> > > > > So I now would prefer to see *fields argument to define_table() >> > > handle >> > > > > all field definitions, and based on type of ...field in fields'... >> I >> > > would >> > > > > collect them and process accordingly. If you _really_ want, you >> could >> > > > > insist that the fields list passed to define table be already >> coalesced >> > > > > (this would simplify core) - that is, all of one together, so that >> a >> > > change >> > > > > is assumed to apply to rest of fields (I think this is prefectly >> > > > > reasonable).... >> > >> > > > > So you see what I am proposing, I would do something like: >> > >> > > > > db.define_table('mytable', >> > > > > 'name', >> > > > > 'birthday date', >> > > > > SQLField( 'some_other_field', 'integer', default=foo()), >> > > > > # and all the following are now assumed to be function calls >> > > > > ) >> > >> > > > > or, alternatively: >> > >> > > > > dyna_fields= ['name', 'birthday date'] >> > >> > > > Note this also can free up other things: ":" can now be a >> separator (so >> > > > spaces in validators can be used), e.g.: >> > >> > > > dyna_fields=['name', 'birthday: date', 'some_comment: text: default >> > > string'] >> > >> > > > I think this opens the possibility for more "regular" processing, >> and >> > > > broader ways of generating tables. >> > >> > > > What do you think? >> > >> > > > - Yarko (... still thinking about this...) >> > >> > > > db.define_table('mytable, *dyna_fields, >> > >> > > > > SQLField( # and so forth....) >> > > > > ) >> > >> > > > > - Yarko >> > >> > > > >> Make sense? I think with a little finesse this could provide >> more >> > > than a >> > > > >> "nice syntax", rather a handy way to automatically generate >> tables >> > > from >> > > > >> descriptors. >> > >> > > > >> Regards, >> > > > >> - Yarko >> > >> > > > >> 2009/4/13 mdipierro <[email protected]> >> > >> > > > >>> Try latest trunk. You can do: >> > >> > > > >>> db.define_table('friendship: person by name birthday notnull, >> dog by >> > > > >>> name ') >> > >> > > > >>> mind that you cannot have both notnull and unique and you cannot >> have >> > > > >>> a unique reference because I just realized we lack a validator >> to do >> > > > >>> it. I will make one and extend this.. >> > >> > > > >>> Massimo >> > >> > > > >>> On Apr 13, 12:26 pm, mdipierro <[email protected]> wrote: >> > > > >>> > Actually it does just >> > >> > > > >>> > db.define_table('friendship' >> > > > >>> > ,SQLField('person_name') >> > > > >>> > ) >> > >> > > > >>> > but I am about to follow your suggestion (with a slight change >> in >> > > > >>> > notation) and do >> > >> > > > >>> > db.define_table('friendship: person by name birthday notnull, >> dog >> > > by >> > > > >>> > name ') >> > >> > > > >>> > generate: >> > >> > > > >>> > db.define_table('friendship' >> > > > >>> > ,SQLField('person',requires=IS_IN_DB(db,'person.id','%(name) >> % >> > > > >>> > (birthday)',notnull = True), >> > > > >>> > ,SQLField('dog',requires=IS_NULL_OR(IS_IN_DB(db,'dog.id','% >> > > > >>> > (name)')), >> > > > >>> > ) >> > >> > > > >>> > Massimo >> > >> > > > >>> > On Apr 13, 11:13 am, DenesL <[email protected]> wrote: >> > >> > > > >>> > > Maybe too short to be useful, but when you get to references >> it >> > > would >> > > > >>> > > be nice to have: >> > >> > > > >>> > > db.define_table('friendship: person.name, dog.name') >> > >> > > > >>> > > But then, does this mean: >> > >> > > > >>> > > db.define_table('friendship' >> > > > >>> > > ,SQLField('person_name' >> > > > >>> > > ,db.person >> > > > >>> > > ,requires=IS_IN_DB(db,db.person,'%(name)') >> > > > >>> > > )... >> > >> > > > >>> > > or >> > >> > > > >>> > > ,SQLField('person_name' >> > > > >>> > > ,db.person.name.type >> > > > >>> > > ,db.person.name.length >> > > > >>> > > ,requires=IS_IN_DB(db,db.person.name) >> > > > >>> > > )... >> > >> > > > >>> > > On Apr 13, 2:16 am, mdipierro <[email protected]> >> wrote: >> > >> > > > >>> > > > In trunk you can now do >> > >> > > > >>> > > > db.define_table('person : Name, Birthday date, Telephone') >> > > > >>> > > > db.define_table('dog: Name, Owner person, Picture upload') >> > >> > > > >>> > > > Is this useful? Look at the source. Is the syntax >> reasonable? >> > >> > > > >>> > > > Massimo >> >> >> > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "web2py Web Framework" 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/web2py?hl=en -~----------~----~----~----~------~----~------~--~---

