Why doesn't a new table column show up in the query results in CakePHP? - mysql

I have added a new column to my table Attributes which already has (id , form_id(foreign key),type,label,size,sequence no,instr)
where instr is the new column i have added.
My application is in CakePHP and MySQL.
I have used the following code to insert into the table Attributes But the field instr alone not inserted.
function saveFieldname($data)//from untitledfieldname
{
$this->data['Attribute']['form_id'] = $this->find( 'all', array(
'fields' => array('Form.id'),
'order' => 'Form.id DESC'
));
$this->data['Attribute']['form_id'] = $this->data['Attribute']['form_id'][0]['Form']['id'];
$this->data['Attribute']['label'] = 'Label';
$this->data['Attribute']['size'] ='50';
$this->data['Attribute']['instr'] ='Fill';
$this->data['Attribute']['type'] = $data['Attribute']['type'];
$this->data['Attribute']['sequence_no'] = $data['Attribute']['sequence_no'];
$this->Attribute->save($this->data);
}
Please suggest me..

The information about the structure of your table is probably cached. Remove the content of "app/tmp/cache/models" and try it again.

Note that in development the debug level in app/config/core.php is usually set to > 1. This means you should never run into the issue in development because Cake will not cache. However, in production, debug is set to 0 in core.php, thus causing cake to start caching.
To add to that, I had removed the cache files in app/tmp/cache/models as dhofstet specified on my production CakePHP app and the find queries were still not grabbing my new column.
--
As well as clearing the model cache files, I set the debug level to 2 on my production site and did page refresh then set it back to 0 and it got it working again. I know this is an ugly approach, but it fixed it for me when no other methods were working.

Related

My UPDATE query in mysql perl is not updating. What am I doing wrong?

I am wanting to take data from mysql, display it, have users edit this data and then save it to the database. I have all currently working except the saving to the database part. I have been lead to believe that the UPDATE query in mysql is how you get this to work. I put an UPDATE query in place and had no luck. Has anyone here experienced this issue before? I have read several posts here and on perl monks about this issue and can't seem to find an answer that solves my problem. I will put some of my code below. Thanks!
my $dbh=DBI->connect("dbi:mysql:survey_one", "user", "password", { PrintError =>0, RaiseError => 1, AutoCommit => 1}) or die $DBI::errstr;
my $edit_sql = q{UPDATE new_survey SET question = ? WHERE title= ?};
my $sthe = $dbh->prepare($edit_sql);
$sthe->execute($questionedit, $marathon);
$sthe->finish();
I'd like to note that if I were to SET the question column to a string like 'does this work?' I would have success. It's when I try to use user input $questionedit, which is defined as
$questionedit = param('editquestion'); This is where users can edit the question field.
Thanks!
The following are the four possible outcomes:
Nothing happens because the code isn't executed.
An exception is thrown because an error occurred (and RaiseError => 1 was used). The exception will end up being printed to STDERR unless caught.
->execute returns the string 0E0 (which is true, but numifies to zero) because no rows were updated because the WHERE clause didn't match any rows.
->execute returns a positive number indicating the number of rows modified.
Determine which case is applicable, and you'll know how to move forward.

How to ignore case using breeze FilterQueryOp

I am using breeze to query data from the server and seem to be running into problems.
Is there a way to filter this data and ignore cases or making the value from the field a lower case?
Example:
var term = "john";
query = query.where("Name", "contains", Term);
The problem I am having is if the 'Name' field contains John with capital 'J', It return false but returns true if I change term to 'John'.
I know this is case issue but how can I make breeze ignore the casing? without using jquery.each.
Thanks. Any help will be greatly appreciated.
In my opinion there is a simpler approach to this.
By default OData is case sensitive, but nonetheless provides functions to transform a string to lower or upper case. So to fire a case-insensitive query to the server simply modify your code as follows:
var term = "john";
query = query.where("tolower(Name)", breeze.FilterQueryOp.Contains, term.toLowerCase());
Thus OData is told to transform the subject to lower case before comparing it to your search string, which has been converted to lower case before sending it to the server.
Ok, there are two parts to this. Breeze supports a LocalQueryComparisonOptions object that is used for all localQueries.
var lqco = new breeze.LocalQueryComparisonOptions({
name: "custom comparison options",
isCaseSensitive: false,
usesSql92CompliantStringComparison: true
});
// either apply it globally
lqco.setAsDefault();
// or to a specific MetadataStore
var ms = new breeze.MetadataStore({ localQueryComparisonOptions: lqco });
var em = new breeze.EntityManager( { metadataStore: ms });
You should set this once at the beginning of your application. In this example, all localQueries performed after this point will be case insensitive.
The problem is that unless your database is ALSO set to "match" these settings ( performing this differs by database vendor), then remote queries against the server will return different results then the same query applied locally.
Basically, Breeze cannot set the "server" side implementation, so the recommendation is usually to create a localQueryComparisons object that matches your server side database settings.
Hope this makes sense.
If anyone run into this problem on an Oracle DB, I added the code above from Jay Traband then modified a logon trigger to alter session variables for DB users.
Set the following values:
ALTER SESSION SET nls_comp = linguistic;
ALTER SESSION SET nls_sort = binary_ci
Hope this helps someone out. I love Breeze!!!

CakePHP added column doesn't appear in query

I have added a new_column to a MyISAM table on a MySQLproduction server.
I have deleted the appropriate model cache file from the /app/tmp/models folder.
Upon reloading the page and inspection, the newly generated cache file for the model INCLUDES the new column.
The new column doesn't appear in SQL queries or results when read with fields => null.
debug($this->read(null, $id));
//Query generates fields: SELECT Model.column_a, Model.column_b, Model.id WHERE ...
//Results do not include the new column
debug($this->read(array('new_column'), $id));
//Query generates fields: SELECT Model.new_column, Model.id WHERE ...
//Results include the new column and id
Possible caveats and additional info:
The table has 39 columns (why would this be a problem?)
The model is an EXTENDED class from a plugin
The new column definition is TEXT DEFAULT null
Previous updates to the table gave expected results
Local development replica of the app doesn't have this issue
The test controller action enables Configure::write(debug => 2)
CakePHP 2.3.6, PHP 5.4.19, MySQL 5.1.70
How to make the Model recognize the new table definition? Are there any other cache systems I should investigate?
Edit #1:
debug($this->ModelName->getDataSource()->describe('table_name'));
// outputs all columns
// ...
'new_column' => array(
'type' => 'text',
'null' => true,
'default' => null,
'length' => null,
'collate' => 'utf8_general_ci',
'charset' => 'utf8'
)
Edit #2:
I have tried disabling the cache completely. Although the model picks up the new column, it is not really a solution.
Configure::write('Cache.disable', true);
// new_column appears in both query and results
Edit #3:
Further debugging shows that there is a discrepancy between these two results:
$this->ModelName->getDataSource()->fields($this->Model, 'ModelName');
//returns fields without new_colum
array_keys($this->ModelName->schema());
//returns fields with new_column
And this temporarily solves the problem:
$ds = $this->ModelName->getDataSource();
$ds->cacheMethods = false;
...
Method caching of the DboSource is the source of this issue. Slowly getting to the bottom of things.. :D
You have to clear all the cache files (but not directories) in app/tmp/cache whenever you update an application that is in production (debug is set to 0).
The actual cache causing problems in this issue was the app/tmp/cache/persistent/_cake_core_method_cache. Don't let the persistent part fool you, as it did me.
See this great answer for more details.
It is probably something related to the Database cache engine: in this case you can solve your issue just changing the query (for example, removing a field using the 'fields' statement). You can even try deleting the CakePHP's model cache: it's located in app/tmp/cache/models.
Happy Coding!
In fact what you can add a bootstrap file if you use a Plugin.
In my global bootstrap file I put:
CakePlugin::load('Myplugin', array('routes' => true, 'bootstrap' => true));
and in Plugin/Myplugin/Config/bootstrap.php I have
<?php
Cache::config('_cake_core_', array(
'engine' => 'File',
'prefix' => 'cake_core_myplugin_',
'path' => CACHE . 'persistent' . DS,
'serialize' => true,
'duration' => '+7 days',
));
?>
I added two columns in one of my models and I faced the same issue has you. Then I deleted all the models and persistent cache files and I change the duration inside my bootstrap file to 1 min.
Finally, my model was ok and reloaded. Later I go back to the initial duration.
It is durty, but it also looks like CakePHP messed up a little bit with cache.
Hope that it can help

Codeignighter Record wont insert

Using CI for the first time and i'm smashing my head with this seemingly simple issue. My query wont insert the record.
In an attempt to debug a possible problem, the insert code has been simplified but i'm still getting no joy.
Essentially, i'm using;
$data = array('post_post' => $this->input->post('ask_question'));
$this->db->insert('posts', $data);
I'm getting no errors (although that possibly due to disabling them in config/database.php due to another CI related trauma :-$ )
Ive used
echo print $this->db->last_query();
to get the generated query, shown as below:
INSERT INTO `posts` (`post_post`) VALUES ('some text')
I have pasted this query into phpMyAdmin, it inserts no problem. Ive even tried using $this->db->query() to run the outputted query above 'manually' but again, the record will not insert.
The scheme of the DB table 'posts' is simply two columns, post_id & post_post.
Please, any pointers on whats going on here would be greatly appreciated...thanks
OK..Solved, after much a messing with CI.
Got it to work by setting persistant connection to false.
$db['default']['pconnect'] = FALSE;
sigh
Things generally look ok, everything you have said suggests that it should work. My first instinct would be to check that what you're inserting is compatible with your SQL field.
Just a cool CI feature; I'd suggest you take a look at the CI Database Transaction class. Transactions allow you to wrap your query/queries inside a transaction, which can be rolled back on failure, and can also make error handling easier:
$this->db->trans_start();
$this->db->query('INSERT INTO posts ...etc ');
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
// generate an error... or use the log_message() function to log your error
}
Alternatively, one thing you can do is put your Insert SQL statement into $this->db->query(your_query_here), instead of calling insert. There is a CI Query feature called Query Binding which will also auto-escape your passed data array.
Let me know how it goes, and hope this helps!

CakePHP parsing query results alternative

I have a query that's returning a LOT of results and my code is running out of memory trying to parse the results... how can I run a query in CakePHP and just get normal results?
By parsing it I mean....
SELECT table1.*, table2.* FROM table1 INNER JOIN table2 ON table1.id = table2.table1_id
With the above query it'll return....
array(
0 => array(
'table1' => array(
'field1' => value,
'field2' => value
),
'table2' => array(
'field1' => value,
'field2' => value
)
)
)
When it parses those results into nested arrays is when it's running out of memory.... how do I avoid this?
I couldn't hate CakePHP any more than I do right now :-\ If the documentation was decent that would be one thing, but it's not decent and it's functionality is annoying.
you could do:
$list = $this->AnyModel->query("SELECT * FROM big_table");
but i dont think that will solve your problem, because if you have, for exemple, 10millon rows.. php wont be able to manage an array of 10millon values...
but you might want to read this two links to change the execution time and the memory limit.. you could also change them on your php.ini
Good Luck!
EDITED
hmm thanks to your question i've learned something :P First of all, we all agree that you're receiving that error because Cake executes the query and tries to store the results in one array but php doesn't support an array that big so it runs out of memory and crashes.. I have never used the classic mysql_query() (i prefer PDO) but after reading the docs, it seems that mysql_query stores the results inside a resource therefore, it's not loading the results on memory, and that allows you to loop the results (like looping though a big file). So now i see the difference... and your question is actually, this one:
Can I stop CakePHP fetching all rows for a query?
=) i understand your frustration with cake, sometimes i also get frustrated with it (could you believe there's no simple way to execute a query with a HAVING clause?? u_U)
Cheers!
I'd suggest you utilize the Containable behavior on your model. This is the easiest way to control the amount of data that's returned. I've confident that this is precisely what you need to implement.
CakePHP :: Containable :: Core Behaviors
You should limit the rows returned from your query (like 500 rows) and allow the user to fetch more rows when needed (next 500 rows at a time). You could do that nicely with the pagination component and a little AJAX.