Skip to content

fields lowercase #106

Closed
Closed

Description

@GoNode5

I used the Mysql World-database as example to test Orm. All the examples for fields are lowercase. Testing with find returned an empty array but the count was correct. It took me a long time to find out that the field defs in MySql table where mixed case. The empty array was not really helping... It also could suggest the find was empty? An error that the fieldname was not found would have been more helpfull?

Activity

  1. dresende commented on Apr 9, 2013

    @dresende
    Owner

    I think you can define the model properties in any case you want. I'm not sure if it will look for the column as you defined it. I'm going to check.

  2. GoNode5 commented on Apr 9, 2013

    @GoNode5
    Author
    var  Country = db.define("country", {
            Code    : { type: "text", size: 3 },
            Name    : { type: "text", size: 52 }
    
    });   
    

    Country.find( {Name:orm.like("n%") }, function (err, countries) {
    console.log(countries[0].Name);
    // console output: Netherlands Antilles

    var  Country = db.define("country", {
            code    : { type: "text", size: 3 },
            name    : { type: "text", size: 52 }
    
    });   
    

    Country.find( {name:orm.like("n%") }, function (err, countries) {
    console.log(countries[0].name);
    // console output: null

  3. dresende commented on Apr 9, 2013

    @dresende
    Owner

    I did not express correctly. When I said you can define the properties as you want, I meant as you need. Your example shows that the driver you're using is case sensitive. I never thought about that. Since ORM does not inspect tables before querying, it doesn't know the properties case. What database are you using?

  4. dresende commented on Apr 9, 2013

    @dresende
    Owner

    Is it postgresql?

  5. dresende commented on Apr 9, 2013

    @dresende
    Owner

    I think it is. I just found that when escaping property names in queries, postgresql is case sensitive. If I don't escape them, it's insensitive... fuck.

  6. dresende commented on Apr 9, 2013

    @dresende
    Owner

    I can't do nothing about this, unless I add an option to perform queries without quoting identifiers (table names and column names). This will probably bite me in the future, I would prefer to keep it as it is. You have to define your properties as you have them in database. I don't like having ucfirst() on columns but if you like it, you probably also like it in db.define().

  7. GoNode5 commented on Apr 9, 2013

    @GoNode5
    Author

    i wrote I used the Mysql ... ucfirst is not needed.... I would prefer rather an error message.

    Querie's seems to be case inseniitive. in both cases the sql is the same
    (orm/mysql) SELECT * FROM country WHERE name LIKE 'n%'

    somehow the resultset is not matched... could you not make this always lowercase

  8. dresende commented on Apr 9, 2013

    @dresende
    Owner

    I don't seem to have a problem with mysql. Are you sure err is null ? When I tested with postgresql it returned me an error.

  9. dresende commented on Apr 9, 2013

    @dresende
    Owner

    Please post mysql server version and orm version.

  10. GoNode5 commented on Apr 9, 2013

    @GoNode5
    Author

    mysql Ver 14.14 Distrib 5.6.10, for Win64 (x86_64)
    2.0.8 (did a fresh new install to a new dir / npm install orm

    var orm = require("orm");

    orm.connect("mysql://_:_@localhost/world", function (err, db) {
    if (err) throw err;

    var  Country = db.define("country", {
            code    : { type: "text", size: 3 },
            name    : { type: "text", size: 52 }
    });
    

    var Country2 = db.define("country", {
    Code : { type: "text", size: 3 },
    Name : { type: "text", size: 52 }
    });

    Country.find( {Name:orm.like("n%") }, function (err, countries) {
    console.log(countries[0].name);
    console.log(countries[0].Name);
    });
    Country2.find( {Name:orm.like("n%") }, function (err, countries) {
    console.log(countries[0].name);
    console.log(countries[0].Name);
    });

    });

    node-test

  11. dxg commented on Apr 10, 2013

    @dxg
    Collaborator

    I can't do nothing about this, unless I add an option to perform queries without quoting identifiers (table names and column names). This will probably bite me in the future, I would prefer to keep it as it is.

    It will, when someone decides to have a field called select or any one of these.

    @GoNode5: Not really sure what's in your databse, so I did some testing of my own:

    var orm = require("orm");
    
    orm.connect("mysql://user:pass@localhost/database", function (err, db) {
      if (err) throw err;
    
      var Country = db.define("country", {
        code : { type: "text", size: 3  },
        name : { type: "text", size: 52 }
      });
      var Country2 = db.define("country", {
        Code : { type: "text", size: 3  },
        Name : { type: "text", size: 52 }
      });
    
      var which = Country2;
    
      if (which == Country)
        var data = [{name: 'nelly'}, {name: 'norbert'}];
      else
        var data = [{Name: 'nelly'}, {Name: 'norbert'}];
    
      which.drop(function(err) {
        which.sync(function(err) {
          if (err) throw err;
    
          which.create(data, function(err) {
            if (err) throw err;
    
            Country.find( { name:orm.like("n%") }, function (err, countries) {
              console.log(countries[0].name, countries[0].Name);
    
              Country2.find( { Name:orm.like("n%") }, function (err, countries) {
                console.log(countries[0].name, countries[0].Name);
                db.close();
              });
            });
          });
        });
      });
    });
    which = Country;
    > nelly undefined
    > nelly undefined
    
    which = Country2;
    > null undefined
    > null undefined
    

    This is a caching issue; if you disable cache on Country2 it outputs correctly:

    var Country2 = db.define("country", {
      Code : { type: "text", size: 3  },
      Name : { type: "text", size: 52 }
    }, {cache: false});
    
    null undefined
    undefined 'nelly'

    There are only two hard things in Computer Science: cache invalidation and naming things.

    In this case, the key for the cache is the table name.

  12. GoNode5 commented on Apr 10, 2013

    @GoNode5
    Author

    @dxg I really dont understand the cache thing I have to study your example:

    I installed MySql locally, included was an database called: World, wich include an allready created and filled table Country: CREATE TABLE country (
    Code char(3) NOT NULL DEFAULT '',
    Name char(52) NOT NULL DEFAULT '',
    You can have mixed case fieldname's in Mysql apperantly... I took the ORM example where fieldnames all are lowercase. These leads to the null showed... The sql query apperently don't care about mixed case (SELECT * FROM country WHERE name LIKE 'n%' showed by node-mysql ) so why do I get an null ?

  13. dxg commented on Apr 10, 2013

    @dxg
    Collaborator

    Ignore the caching thing; it's not the issue you've hit..

    I finally understand. I also recreated your table, and got the same problem you did with mysql.

    ORM is case sensitive. Some databases are/arent.
    This is where the confusion comes from.

    @dresende: from what I can see, the data from the database is being discarded here due to different case.
    If the user calls Model.sync() there won't be a problem, but if the table is pre-existing, and with different column case, it will continue to trip people up..
    I'm not sure of a good solution, will have a think.

    EDIT:

    SELECT `name` FROM country WHERE `name` LIKE 'n%';

    name: Norway

    SELECT `Name` FROM country WHERE `Name` LIKE 'n%';

    Name: Norway

    Hmm so the database is returning the right thing. The issue lies either in the mysql driver or ORM. Will continue investigating tomorrow..

  14. GoNode5 commented on Apr 10, 2013

    @GoNode5
    Author

    @dxg thnx... well explained your english is much better... As said before, I think its a mismatch between the results set and the fields in the model. Although Mysql use mixcased you can't have 2 fields like Test and test... So like the query that only use lowercase (SELECT * FROM country WHERE name LIKE 'n%' ) you should lowercase the match between the result fields and the model fields... then it doesn't matter wether the model or sql or table/colums uses mixcase

  15. dresende commented on Apr 10, 2013

    @dresende
    Owner

    Mysql driver returns the columns right, as were defined when creating the table. ORM is case sensitive in this case because js object keys are case sensitive. I'm not sure it will be easy to make it insensitive.

  16. 7 remaining items

  17. dresende commented on Apr 11, 2013

    @dresende
    Owner

    Don't worry, I'm going to change this.

  18. dxg commented on Apr 11, 2013

    @dxg
    Collaborator

    Yeah, defined properties [normal+association].

    I noticed that sometimes hasOne association properties aren't created:

    var Country = db.define("country", {
      code : { type: "text", size: 3  },
      name : { type: "text", size: 52 }
    });
    Country.hasOne('world', ...);
    c = new Country();
    console.log(c.code)
    console.log(c.world_id)

    will print out:

    null
    undefined
    

    since association properties arent created when you call new (but they are when you call find/get, or if you call new and supply world_id).

    It sounds like models should have a list of all defined properties to make this more consistent and less error prone, rather than compiling the list each time.
    It also sounds like you'd need such a list to implement the select col1, col2.. behaviour, so we should win all round :)

  19. dresende commented on Apr 11, 2013

    @dresende
    Owner

    Yes, I have a change with that list. I'm just fixing this list to have associations.

  20. dresende commented on Apr 12, 2013

    @dresende
    Owner

    Please test this change when you can.

  21. GoNode5 commented on Apr 12, 2013

    @GoNode5
    Author
        var  Country = db.define("country", {
                code    : { type: "text", size: 3 },
                name    : { type: "text", size: 52 }
        })
    
    Country.find( {Name:orm.like("n%") }, function (err, countries) {
     console.log(err);
    
    { [Error: ER_BAD_FIELD_ERROR: Unknown column 'id' in 'field list'] code: 'ER_BAD
    _FIELD_ERROR', index: 0 }
  22. GoNode5 commented on Apr 12, 2013

    @GoNode5
    Author

    cant you give the model, like methods, an search/find option where you can define searches...

    default will be all/*

    find: {
                shortList: {code+name};
                longlist: {code+name+language};
            }
  23. dresende commented on Apr 12, 2013

    @dresende
    Owner

    @GoNode5 : you should define the model properties as you have them in the table. In your case, at least name should be Name.

    cant you give the model, like methods, an search/find option where you can define searches...

    What do you mean by this? I did not understand your example.

  24. GoNode5 commented on Apr 12, 2013

    @GoNode5
    Author

    error is about 'id' ? Changing from 'name' to 'Name' didnt help. (btw there is no id field, primary key is Code in the country table)

      var  Country = db.define("country", {
                Code    : { type: "text", size: 3 },
                Name    : { type: "text", size: 52 }
        });
    { [Error: ER_BAD_FIELD_ERROR: Unknown column 'id' in 'field list'] code: 'ER_BAD
    _FIELD_ERROR', index: 0 }

    find would be a property of the model where you could predefine column(s) to use in find, instead of define them for every Find

    Model.find( [columns /pre defined finds from model / or select all*][ conditions ] [, options ] [

  25. dresende commented on Apr 12, 2013

    @dresende
    Owner

    If primary key is Code, you're doing it wrong. Your Country model should be defined like this:

    var Country = db.define("country", {
        Name : { type: "text", size: 52 }
    }, {
        id : "Code"
    });
  26. GoNode5 commented on Apr 12, 2013

    @GoNode5
    Author

    sorry forget the syntax... now its working the actual query has 2x Code?

        var  Country = db.define("country", {
                Code    : { type: "text", size: 3 },
                Name    : { type: "text", size: 52 },
                Region    : { type: "text", size: 26 },
                Continent : [ "Asia", "Europe", "North America ", "Africa", "Oceania","Antartica",   "South America" ],         
        }, {
        id : "Code"
        });
    
    Country.find( {name:orm.like("n%") }, function (err, countries) {
     console.log(countries[0].Code);
     console.log(countries[0].Name);
     console.log(JSON.stringify(countries[0]));
    })

    (orm/mysql) SELECT Code, Code, Name, Region, Continent FROM country
    WHERE name LIKE 'n%'
    ANT
    Netherlands Antilles
    {"Code":"ANT","Name":"Netherlands Antilles","Region":"Caribbean","Continent":"No
    rth America"}

  27. dresende commented on Apr 12, 2013

    @dresende
    Owner

    You added id: "Code" but you forgot to remove Code from properties.

  28. GoNode5 commented on Apr 13, 2013

    @GoNode5
    Author

    it's very confusing... I would rather have:

    Code : { type: "text", size: 3,primary-key, unique, required},
    Name : { type: "text", size: 52, required },

  29. dresende commented on Apr 16, 2013

    @dresende
    Owner

    Primary keys are not defined in the properties. The primary key is auto included by ORM. If you add it to the properties it will be duplicated and probably fail a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions