Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding a new int column causes the name of the column to be populated in existing rows #157

Closed
danelkhen opened this issue Dec 29, 2016 · 8 comments

Comments

@danelkhen
Copy link

I've added a new column to an existing table, and all existing rows were had the string name of the new column name in the new column value.

Steps to reproduce:

Start with this class, run and create db:

@Table()
export class MyTable {
    @PrimaryColumn() key: string;
    @Column(CT.SIMPLE_ARRAY, { nullable: true }) files: string[];
}

Insert some rows, modify the code to include another column

@Table()
export class MyTable {
    @PrimaryColumn() key: string;
    @Column(CT.SIMPLE_ARRAY, { nullable: true }) files: string[];
    @Column(CT.INT, { nullable: true, default: null }) someNumber: number;
}
SELECT * FROM my_table
id files someNumber
1 a,b,c someNumber
2 d,e,f someNumber
3 g,h,i someNumber
@danelkhen
Copy link
Author

Also happens in a STRING column

@pleerock
Copy link
Member

nope, it cant be truth. I add columns almost every day and never faced such a problem. What database are you using? Maybe something wrong with how it shows the view of the table? Also since someNumber is an integer number, it can't have someNumber value in it.

@danelkhen
Copy link
Author

I know it doesn't make much sense, but it happens I promise! :-)

actually, I think I forgot to mention something that might be crucial - I'm using sqlite provider. (sqlite might not be actually checking the validity of the data). If you want me to turn on some verbose sql logging to send you lemme know what you need me to do.

@pleerock
Copy link
Member

I'll check this issue with sqlite. Can you enable your logging and send me queries ORM is executed for you?

createConnection({
    /// ...
    logging: {
         logQueries: true
    }
});

@danelkhen
Copy link
Author

Sure, here it is:
first run: (without the new column)

executing query: SELECT * FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence'
executing query: BEGIN TRANSACTION
executing query: CREATE TABLE "by_filename" ("key" character varying(255) NOT NULL, "selectedFiles" text, PRIMARY KEY(key))
executing query: COMMIT

second run: (with the new column)

executing query: SELECT * FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence'
executing query: PRAGMA table_info("by_filename")
executing query: PRAGMA index_list("by_filename")
executing query: PRAGMA foreign_key_list("by_filename")
executing query: PRAGMA table_info("movie")
executing query: PRAGMA index_list("movie")
executing query: PRAGMA foreign_key_list("movie")
executing query: PRAGMA index_info("sqlite_autoindex_by_filename_1")
executing query: BEGIN TRANSACTION
executing query: CREATE TABLE "temporary_by_filename" ("key" character varying(255) NOT NULL, "selectedFiles" text, "tmdbId" character varying(255), PRIMARY KEY(key))
executing query: INSERT INTO "temporary_by_filename" SELECT "key", "selectedFiles", "tmdbId" FROM "by_filename"
executing query: DROP TABLE "by_filename"
executing query: ALTER TABLE "temporary_by_filename" RENAME TO "by_filename"
executing query: COMMIT

I believe I see the problem here, since the query refers the new column in the old table "tmdbId" as a quoted string, sqlite probaby just uses the actual string value when migrating the data instead of the column's value, as this column doesn't exist.

@danelkhen
Copy link
Author

Perhaps this could help?

https://www.sqlite.org/lang_keywords.html

If a keyword in single quotes (ex: 'key' or 'glob') is used in a context where an identifier is allowed but where a string literal is not allowed, then the token is understood to be an identifier instead of a string literal.

If a keyword in double quotes (ex: "key" or "glob") is used in a context where it cannot be resolved to an identifier but where a string literal is allowed, then the token is understood to be a string literal instead of an identifier.

@pleerock
Copy link
Member

fixed and released in 0.0.7-alpha.1. Do npm i typeorm@0.0.7-alpha.1 and try it.

@danelkhen
Copy link
Author

Tested, works, thanks!
(great library btw 👍 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants