CakePHP database table, missing datasource default - database

I found this similar question but my problem is different.
I moved my CakePHP 2.2 application to another server. There exists no problem before migration. Most of the things works fine after migration. I can reach most of my database tables etc. But when I try to reach one of my table I get this error:
"Error 500: Table stats for model Stat was not found in datasource default."
To solve this, I checked this folder:
"/app/tmp/cache/models"
In that folder there is a file for each of my tables
myapp_cake_model_default_mydatabase_table1
myapp_cake_model_default_mydatabase_table2
myapp_cake_model_default_mydatabase_table3
etc..
But there is no file for stats table. Can it be the problem? Or how can I solve this?
(Permission for "/app/tmp/cache/models" folder is 755)
In Database.php I have this:
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'myuser',
'password' => 'mypass',
'database' => 'mydatabase',
'prefix' => '',
'encoding' => 'utf8',
);
Edit:
As I noted in thaJeztah's answer's comments, after removing all files inside app/tmp/cache/persistent problem solved. CakePHP created new model cache files and it worked. After one year I found out the real problem. The problem was setting cake model files' clear duration. I set clearing cache to +999 days, so model files aren't regenerated. While making model changes you can set lower values for model cache clear:
Cache::config('_cake_model_', array(
'engine' => "File",
'prefix' => "myapp_". 'cake_model_',
'path' => CACHE . 'models' . DS,
'serialize' => ($engine === 'File'),
'duration' => "+999 days"
));

Have you checked your database, e.g. in phpMyAdmin or MySql workbench? Does the table exist in the database?
The error message indicates that the table could not be accessed using the default connection. It's possible that the table is really missing, or that the user you're using to connect to the database does not have the right permissions for that table.
If you migrated the database from another server, did you get error messages while importing? If you did not create a dump enclosed in a transaction, it's possible that the database dump was only partially imported.
[update] this suggestion solved the problem;
Remove all files from app/tmp/cache/persistent and /app/tmp/cache/models then enable debugging. Your SQL log/debug should show the queries that CakePhp is using to detect if the tables exist in the database. Also you'll be able to check if Cake writes to the tmp files without problems

If this is helpfull for anyone in 2020.
I had this problem even with full permissions to the model. I tried doing like #theJeztah suggested which was clearing cache/persistent but the problem persisted. What ended up working was switching Configure::write('debug', 0) to Configure::write('debug', 2) in the app/core file. Presumably on debug it clears the cache better.

Related

Data Source missing

I run my CakePHP project on localhost. When I fill form, after clicking submit button it shows the following error:
Missing Datasource Configuration
Error: The datasource configuration Array was not found in
database.php.
I actually configured a datasource it and it looks like:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Postgres',
'persistent' => false,
'host' => 'localhost',
'login' => 'arwinder',
'password' => 'root',
'database' => 'sh_db',
'prefix' => '',
//'encoding' => 'utf8',
);
public $test = array(
'datasource' => 'Database/Postgres',
'persistent' => false,
'host' => 'localhost',
'login' => 'arwinder',
'password' => 'root',
'database' => 'sh_db',
'prefix' => '',
//'encoding' => 'utf8',
);
}
... but it's getting ignored.
I had a similar issue when trying to work with data sanitation (it's a weird use case, what can I say).
The documentation for sanitize::escape says,
"The name of the database to quote the string for, as named in your
app/Config/database.php file."
It does not, in fact, take the name of the database eg. 'mydatabase' nor does it accept the host eg. 'localhost', nor does it accept the 'datasource' eg. 'Database/Mysql'. When given any of these VALUES, you get the error mentioned in the question.
What you actually need is the name of the "Datasource" to use. Again, the documentation for 'Datasource' fails to answer this topic.
I was stumped. So I searched for that error and found this unanswered post.
I finally found a solution thorough shear dumb luck, and as this post is still the highest result for this error on Google, I came back to answer it.
What you actually need is the variable name (key not value) as listed in the above mentioned config file. eg. $default or $test or $what_have_you. You then provide 'default', 'test' or 'what_have_you' depending on hostname.
Here's what boggles my mind the most. If the Datasource changes from 'production' to 'testing' and also 'local_dev' knowing which one is in use at any given time is critical to making Sanitise:escape() work.
But hold on a second... if you're doing that, you basically set the datasource to $default using a constructor method as documented here on SO so in all actuality, this mysterious 'Datasource' it's almost always going to be 'default' unless it's set on the fly, as an override, in your model which would be known while you're Sanitizing for a manual query anyway.
In fact, the default for this parameter is indeed, 'default'. It's not a required parameter at all, but because the documentation doesn't list it as optional or provide a defined default parameter (on that particular page) one might assume that it is required.
Anyway, the answer is to not provide a $datasource unless you are using $useDBConfig to specify a different datasource in your Model already.

CakePHP 2.x: Custom Logging

I've got a CakePHP application that receives instant payment notifications from PayPal. I'd like to log the data that gets posted by PayPal. I could easily do that using something like this:
file_put_contents(LOGS . 'ipns.log', date('Y-m-d H:i:s ') . print_r($_POST, true) . "\n", FILE_APPEND|LOCK_EX);
But I prefer to do things "the CakePHP way™" whenever possible. I've already looked through the "Core Libraries > Logging" section of CakePHP's cookbook and am having trouble understanding it. I know it's not correct to do this:
CakeLog::write('ipns', print_r($_POST, true));
Although the above does seem to work, it can also cause problems, as shown here.
So what is the CakePHP way to do this? Or should I just use the raw PHP shown at the top of this question?
What you want is explained here http://book.cakephp.org/2.0/en/core-libraries/logging.html#creating-and-configuring-log-streams
But I would suggest you to read the whole page and not just this section.
I would write the ipn to a database table field by field and not into a file log. I can tell you this based on my experience with the paypal API. The advantages are obviously, you can for example lookup the ipns for an order, search for errors and so on.
According to Writing to log paragraph of Logging section of the 2.x cookbook:
CakeLog does not auto-configure itself anymore. As a result log files
will not be auto-created anymore if no stream is listening. Make sure
you got at least one default stream set up, if you want to listen to
all types and levels. Usually, you can just set the core FileLog class
to output into app/tmp/logs/:
CakeLog::config('default', array(
'engine' => 'File'
));
So, in order to make CakeLog::write('ipns', print_r($_POST, true)); to write to custom file app/tmp/logs/ipns.log you need in app/Config/bootstrap.php instead of:
/**
* Configures default file logging options
*/
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
'engine' => 'File',
'types' => array('notice', 'info', 'debug'),
'file' => 'debug',
));
CakeLog::config('error', array(
'engine' => 'File',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'error',
));
write:
/**
* Configures default file logging options
*/
App::uses('CakeLog', 'Log');
CakeLog::config('default', array(
'engine' => 'File'
));

CakePHP not loading associated properties with model on production server

This is a weird one.
I have a local server on which I develop apps. A product review app I developed works flawlessly on it, and utilizes Cake's associative modeling ($hasMany, $belongsTo, et. al.).
After pushing this app up to a production server, it fails. Gives me an error message:
Notice (8): Undefined property: AppModel::$Product [APP/controllers/reviews_controller.php, line 46]
ReviewsController::home() - APP/controllers/reviews_controller.php, line 46
Dispatcher::_invoke() - CORE/cake/dispatcher.php, line 204
Dispatcher::dispatch() - CORE/cake/dispatcher.php, line 171
[main] - APP/webroot/index.php, line 83
I've debug()'d $this and it shows, plain as day, that, while the local server is loading the associated models, the production server is not. The databases are mirror duplicates (literally, the production server was imported from the dev db), and I can manually load models, which tells me it's connecting to the DB just fine.
What on Earth is going on?
UPDATE
The sql query from the production server is this:
SELECT `Review`.`id`, `Review`.`title`, `Review`.`product_id`, `Review`.`score`, `Review`.`submitted`, `Review`.`reviewed`, `Review`.`right`, `Review`.`wrong`, `Review`.`user_id`, `Review`.`goals`
FROM `reviews`
AS `Review`
WHERE 1 = 1
ORDER BY `Review`.`submitted` desc LIMIT 10
The sql query from the dev server is this:
SELECT `Review`.`id`, `Review`.`title`, `Review`.`product_id`, `Review`.`score`, `Review`.`submitted`, `Review`.`reviewed`, `Review`.`right`, `Review`.`wrong`, `Review`.`user_id`, `Review`.`goals`, `User`.`id`, `User`.`username`, `Product`.`id`, `Product`.`name`
FROM `reviews`
AS `Review`
LEFT JOIN `users` AS `User` ON (`Review`.`user_id` = `User`.`id`)
LEFT JOIN `products` AS `Product` ON (`Review`.`product_id` = `Product`.`id`)
WHERE 1 = 1
ORDER BY `Review`.`submitted` desc LIMIT 10
UPDATE 2
Here's some of the code the errors point to:
$title = $this->Review->Product->find( 'first', array( 'fields' => array( 'Product.name' ), 'conditions' => array( 'Product.id' => $filter ) ) );
UPDATE 3
<?php
class Review extends AppModel {
var $name = 'Review';
var $displayField = 'title';
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
?>
I had this problem, and for me it was due to a missing field in one of the database tables. I'd triple-check to make sure both DB's are exactly the same (although you said they were...): feel free to use this 7-year-old app to check them :D http://www.mysqldiff.org/
Other people with this issue talked about filename issues and that all files should be lowercased, so that may be something to check as well...
Actually - from a quick glance it might be worth using containable to make sure your data calls are consistent.
If you don't want to go through the hassle of adding containable (but I would urge you to do so - it is one my favourite features of cakephp), you may want to set recursive in your find() call just to make sure the associated models are loaded.
Do you have a way of looking at the files on the server without going through ftp? I had a problem similar to this where the timestamps were messed up on the files and the server would not update the file. I had to delete the files, and then re upload them. You may have already tried this but I just thought I would suggest the possibility. Maybe some of those files are outdated on the server.
Have a great day!
Can you pastebin the Review model, Product model, AppModel, AppController, and the controller you are getting the error from.
The line:
Notice (8): Undefined property: AppModel::$Product [APP/controllers/reviews_controller.php, line 46]
Seems to indicate the Review Model is loading the AppModel and not the file you want it to. In that case the Review model won't have a Product association.
you can print the stacktrace out to see, here's some code I snatch from php.net
echo "<div>Stack<br /><table border='1'>";
$aCallstack=debug_backtrace();
echo "<thead><tr><th>file</th><th>line</th><th>function</th><th>args</th></tr></thead>";
foreach($aCallstack as $aCall)
{
if (!isset($aCall['file'])) $aCall['file'] = '[PHP Kernel]';
if (!isset($aCall['line'])) $aCall['line'] = '';
echo "<tr><td>{$aCall['file']}</td><td>{$aCall['line']}".
"</td><td>{$aCall['function']}</td><td>";
debug (($aCall['arg']));
echo "</td></tr>";
}
echo "</table></div>";
die();
It's gonna be hard looking through all that though.

Does CakePHP finderQuery work with SQL Server? Where would I debug that?

I'm new to cakePHP, so I may be missing the obvious.
The system is running the latest download using Microsoft SQL Server 2005 as database. I appreciate that is slightly unusual, but having fixed the URL rewrite I have seen no other issues.
I'd like use a custom finderQuery, but I cannot even seem to replace the default. Specifically if I use
var $hasMany = array(
'RecyclateTypeConversion' => array(
'className' => 'RecyclateTypeConversion',
'foreignKey' => 'recyclate_type_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => 'select RecyclateTypeConversion.* from recyclate_type_conversions AS RecyclateTypeConversion WHERE RecyclateTypeConversion.recyclate_type_id IN ({$__cakeID__$});',
'counterQuery' => ''
),
};
I see this error
Notice (8): Undefined index:
RecyclateTypeConversion
[CORE\cake\libs\model\datasources\dbo_source.php,
line 1099]
However the SQL debug output confirms that the query itself runs fine and returns 4 records, and the view runs perfectly when the finderQuery is not specified. I've tried for other hasMany tables too - with exactly the same issue.
I've attempted to replace the select all with specific field selects but I still see the same result. Certainly the query looks correct according to the manual - so what is the issue (and could it be related to using MSSQL?)
EDIT: Also, as this hasn't picked up any answers yet, what would be the best approach to debugging this? I've started hunting through the cake debugging class, but so far with no results that have enlightened me. Of course if there is a problem I'll be submitting the fix back to the project.
Have you checked that there is actually a model called RecyclateTypeConversion and that it exists with a filename according to the CakePHP conventions? I.e. is there a models/recyclate_type_conversion.php and in that file, is the name of the model defined as RecyclateTypeConversion.
The error that you're getting seems to hint that there's something wrong with that model name, as it cannot find the associated index.
Try removing the alias from the select - the casting in in the "AS RecyclateTypeConversion" part should handle that for you. I also like to wrap custom queries in double quotes. I might just be paranoid but string parsing errors have bit me in the ass before.
var $hasMany = array(
'RecyclateTypeConversion' => array(
'className' => 'RecyclateTypeConversion',
'foreignKey' => 'recyclate_type_id',
'dependent' => false,
'finderQuery' => "select * from recyclate_type_conversions AS RecyclateTypeConversion WHERE RecyclateTypeConversion.recyclate_type_id IN ({$__cakeID__$});",
);
Also, I highly suggest you use the DebugKit plugin and post back to us the query log and a debug output of the find results that cause the errors.
did you go through it step by step?
try to get everything (all data)
try conditions
try "containable" behavior to create your query, which makes things a lot easier in my opinion
Have you tried CakePHP Debug Kit

How do I get zend to recognize the paths to Propel ORM

I am trying to get Propel to work in my Zend app, it seems that I can get the Propel library to load (from library/propel) but when called I get the exception: 'No connection information in your runtime configuration file for datasource [default]' (when I try to make a connection: 'Propel::getConnection'). My Db is not even named 'default'. I have this in my bootstrap.php from another SO question/answer:
require_once 'propel/Propel.php';
Propel::setConfiguration($this->getOptions('propel/MyPropel-conf.php'));
Propel::initialize();
// so we can get the connection from the registry easily
return Propel::getConnection();
I want the Propel configs (classmap conf as well) to be in the '/application/configs' (copies are there too right now), but I thought If I can get Propel to load from library/propel, then maybe moving my 'conf' files there, I may get them to load too. It seems that if I 'force' the config, by manually loading the params, or if I seem to get it in a temporary 'right' location (or use an absolute path), the exception I then get is this:
'Unable to open PDO connection [wrapped: SQLSTATE[28000] [1045] Access denied for user 'www-data'#'localhost'
As if Propel is not paying any attention to my configs.
My config looks like this; converted from the xml:
$conf = array (
'datasources' =>
array (
'unmActTestDB' =>
array (
'adapter' => 'mysql',
'connection' =>
array (
'dsn' => 'mysql://root:PASSWORD#localhost/unmActTestDB',
),
),
'default' => 'unmActTestDB',
),
'log' =>
array (
'ident' => 'propel-act',
'level' => '7',
),
'generator_version' => '1.5.6',
);
$conf['classmap'] = include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classmap-unmActTestDB-conf.php');
return $conf;
If it helps, I still have the Zend PDO DB adapter loading in the application.ini file too, would that cause a clash?. Is there a standard way to get Propel to work with Zend? Or can anyone see what I'm doing wrong?
I have been to several posts here on SO, and a couple popular posts like this one The Adventures Of Merging Propel With Zend Framework and this one at Zend's dev zone Integrating Propel with the Zend Framework, among others including the Propel Docs. They have been helpful, but I am really struggling with this. Thanks in advance! My current Zend Directory structure looks like this (w/ the two propel confs also in the library/propel folder:
What I ended up doing is this:
I got a good grip on how to generate my models from a 'reverse' using Propel. It created (as before) a 'schema.xml' file for me to build my models with.
Also my 'runtime.xml' file was incorrect for my needs, after the build I was not connecting to the right database because of my omission of a few tags, overall it is quite simple though:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<log>
<ident>unmActTestDB</ident>
<level>7</level>
</log>
<propel>
<datasources default="unmActTestDB">
<datasource id="unmActTestDB">
<adapter>mysql</adapter>
<connection>
<dsn>mysql:host=localhost;dbname=unmActTestDB</dsn>
<user>zend</user>
<password>PASSWORD</password>
<database>unmActTestDB</database>
</connection>
</datasource>
</datasources>
</propel>
</config>
The 'dsn' tag has to be in the format above with the addition of the 'user', 'password', and the 'database' tags. This fixed my issue with the database connection errors. As quoted above (and here) the exception thrown was: 'No connection information in your runtime configuration file for datasource [default]'
As far as the loading of my models goes, I ended up putting them in my 'library' folder, I already have that folder autoloading in my app, plus it seemed like a good place form them.
here is an image of my 'updated' directory structure:
Note the addition of the 'unmActTestDB' folder in my directory, this is my ORM models.
Another thing to note is that I put my generated 'conf' files into my 'application/configs' folder. These are correct now, after the correction of the runtime.xml file and a 'rebuild'.
As a side note, I had to edit my 'schema.xml' file by hand (several times :) )...The original database used plural names for the tables, so I edited all the 'phpname' declarations (attributes actually, on the declaration tag) to be singular so I wouldn't access an object called 'Users'...instead I can now access a 'User' object. I kept the table names the same (tables are plural, and I won't have any issues importing the existing data, etc.) This was suggested by an answer to another one of my questions, see here How to get related object Propel ORM.
The other big edit I made was to add primary key declarations (again, attributes) for the many SQL views in the DB, also I added a 'readonly' and a 'noSQL' attributes to the declarations, this way I will have access (through the Propel models) to my views.
And, just to be thorough, and for those who are interested here is the addition to my 'bootstrap.php' file that does my 'Propel Init' for me...
protected function _initPropel()
{
$this->_logger->info('Bootstrap ' . __METHOD__);
require '../library/propel/Propel.php';
Propel::init(APPLICATION_PATH . '/configs/unmActTestDB-conf.php');
Propel::initialize();
return Propel::getConnection();
}
Another NOTE: the '$this->_logger->info('Bootstrap ' . METHOD);' calls my 'logging' method that just tells 'firePHP' that this method has loaded. The /configs/unmActTestDB-conf.php' calls the second 'conf' file that Propel generates... and here is the 'corrected' version of that file (the unmActTestDB.conf file that is), Note the changes in the 'connection' array.
<?php
// This file generated by Propel 1.5.6 convert-conf target
// from XML runtime conf file runtime-conf.xml
$conf = array (
'datasources' =>
array (
'unmActTestDB' =>
array (
'adapter' => 'mysql',
'connection' =>
array (
'dsn' => 'mysql:host=localhost;dbname=unmActTestDB',
'user' => 'zend',
'password' => 'PASSWORD',
'database' => 'unmActTestDB',
),
),
'default' => 'unmActTestDB',
),
'log' =>
array (
'ident' => 'unmActTestDB',
'level' => '7',
),
'generator_version' => '1.5.6',
);
$conf['classmap'] = include(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'classmap-unmActTestDB-conf.php');
return $conf;
I am off and running now! This was a great way to go, otherwise I was looking and writing sooo many mapping classes for my app. Propel (currently) generates over 300 models for this application! Plus the base classes, it would take me forever...

Resources