I asked this question on the CakePHP google-group but didn't find any resolution, so hopefully will have better luck here.
I've been developing on CakePHP for a bit and decided to have a
localhost version on MAMP so that I could demo my app to people
without being dependent on an Internet connection.
We have a couple of complex MySQL queries being made, and using
$this->query('SELECT...');
We've placed these in the appropriate models within a function to remove all this logic from the controller. Hence from the Controller we'll have something like
$this->Users->getMeSomething($variable);
, that goes to the user.php
model and runs that function. This works fine on our live and dev
sites, but for some reason on MAMP I'm getting an error whenever this type of call is made, as an example of one of the calls:
Error:
Warning (512): SQL Error: 1064: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the
right syntax to use near '__getUsersForUsers' at line 1 [CORE/cake/
libs/model/datasources/dbo_source.php, line 525]
Context:
DboSource::showQuery() - CORE/cake/libs/model/datasources/
dbo_source.php, line 525
DboSource::execute() - CORE/cake/libs/model/datasources/
dbo_source.php, line 201
DboSource::fetchAll() - CORE/cake/libs/model/datasources/
dbo_source.php, line 336
DboSource::query() - CORE/cake/libs/model/datasources/dbo_source.php,
line 297
Model::call__() - CORE/cake/libs/model/model.php, line 441
Overloadable::__call() - CORE/cake/libs/overloadable_php5.php, line 52
AppModel::__getUsersForUsers() - [internal], line ??
UsersController::view() - APP/controllers/users_controller.php, line
401
Object::dispatchMethod() - CORE/cake/libs/object.php, line 118
Dispatcher::_invoke() - CORE/cake/dispatcher.php, line 227
Dispatcher::dispatch() - CORE/cake/dispatcher.php, line 194
[main] - APP/webroot/index.php, line 88
Line 88 on webroot is this: $Dispatcher->dispatch($url);
I've tried both 1.2 and 1.2.5 of CakePHP. MySQL on MAMP is 5.1.31 and on my host, MediaTemple, is 5.1.26-rc
Thanks for any help
What happens if you force cake to echo the query, and you try to run it manually in a mySQL client? It looks like your local version is creating a different query than the version on your host -- since mySQL is complaining about syntax.
Found a solution. It has nothing to do with MAMP, in fact we found this bug on our dev server eventually, but not our live server.
Basically, the Cake core's were different on both servers - but minutely so (one was RC, the other was the final). The older one was able to interpret the HABTM model relationship, but the newer core's don't unless you explicitly specify them (this must be a bug since I followed all the naming conventions).
So here's how it will work:
- you have a model user.php and tag.php
- In user.php, you will have a HABTM relationship with the Tag model
- In that array, add the field: 'with' => 'UsersTag'
- Do the same for tag.php
This way CakePHP doesn't have to figure out what the model name is (although it should be able to)
Related
I have a database with a lot of nonmanaged tables which I'm using for a django app. For testing I'm wanting to use the --keepdb option so that I don't have to repopulate these tables every time. I'm using MariaDB for my database. If I don't use the keepdb option everything works fine, the test database gets created and destroyed properly.
But when I try to run the test keeping the database:
$ python manage.py test --keepdb
I get the following error:
Using existing test database for alias 'default'...
Got an error creating the test database: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'CREATE DATABASE IF NOT EXISTS test_livedb ;\n SET sql_note' at line 2")
I assume that this is an issue with a different syntax between MariaDB and MySQL. Is there anyway to get the keepdb option to work with MariaDB?
thanks very much!
For what it's worth: This bug was introduced in Django 2.0.0 and fixed in Django 2.1.3 (https://code.djangoproject.com/ticket/29827)
Two things - check out Factory Boy (for creating test data) and I would suggest checking out Pytest as well. With non-managed tables, the issue I think you'll run into is that (at least in my experience) django won't create them in the test environment and you end up running into issues because there is no migration file to create those tables (since they're unmanaged). Django runs the migration files when creating the test environment.
With Pytest you can run with a --nomigrations flag which builds your test database directly off the models (thus creating the tables you need for your unmanaged models).
If you combine Pytest and Factory Boy you should be able to come up with the ability to setup your test data so it works as expected, is repeatable and testable without issue.
I actually approach it like this (slightly hacky, but it works with our complex setup):
On my model:
class Meta(object):
db_table = 'my_custom_table'
managed = getattr(settings, 'UNDER_TEST', False)
I create the UNDER_TEST variable in settings.py like this:
# Create global variable that will tell if our application is under test
UNDER_TEST = (len(sys.argv) > 1 and sys.argv[1] == 'test')
That way - when the application is UNDER_TEST the model is marked as managed (and Pytest will create the appropriate DB table). Then FactoryBoy handles putting all my test data into that table (either in setUp of the test or elsewhere) so I can test against it.
That's my suggestion - others might have something a little more clear or cleaner.
I have SQLite and MySQL installed on my local and development machine respectively. Following is working fine on my local machine(with SQLite):
select_single = {'date': "strftime('%%Y-%%m-%%d',projectName_Modelname.created)"}
queryset.extra(select=select_single)
But since strftime doesn't work with MySQL(link), I tried using DATE_FORMAT() as suggested in given link and other places too.
Though now when I execute below:
select_single = {'date': "DATE_FORMAT(projectName_Modelname.created, '%%Y-%%m-%%d')"}
queryset.extra(select=select_single)
Following error comes:
DatabaseError: (1054, "Unknown column 'projectName_Modelname.created' in 'field list'")
where 'created' is Datetime field in Django model 'Modelname' of app 'projectName'
To debug when I replace projectName_Modelname.created with NOW() no error comes. I have also tried just Modelname.created instead of projectName_Modelname.created though with no benefit?
Note: I am using Django1.5.5
I think it should be something like:
date_raw_query = {'date': "date_format(created, '%%Y-%%m-%%d')"}
and then try
queryset.extra(select=date_raw_query)
Hope that works in your setup. I have tried this on Django 1.7 and MySQL and seems to be working.
Also remember that if SQL errors start coming up, you can always do a print queryset.extra(select=date_raw_query).query to see what might be going wrong.
And when it comes to writing compatible code between SQLite and MySQL like this one, writing a custom MySQL function has been suggested here
But I would suggest otherwise. It's better to have a similar dev environment with MySQL setup in local and also, upgrade Django as soon as possible. :P
I have made sure that the columns match the 'column to export' field in the columns tab, not null columns have data, tried in both csv and txt but all i get is a message saying:
import/export job created
Nothing else: no errors, no warning, no completion.
windows 7 os
Version1.4
CopyrightCopyright 2013 - 2017, The pgAdmin Development Team
Python Version2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:19:22) [MSC v.1500 32 bit (Intel)]
Flask Version0.11.1
Application ModeDesktop
till then ill try via psql
Just a guess, but are you trying this as a superuser? I'm having the same issue and so trying to write it as a COPY statement, but get this response:
ERROR: must be superuser to COPY to or from a file
SQL state: 42501
Hint: Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.
I'm not sure, but maybe the functionality in pgAdmin just constructs a COPY statement, then isn't properly relaying the error message back to you when it fails.
Sounds like psql is the right way to go, though.
I recently installed SQLAlchemy-FullText-Search dependency in (https://github.com/mengzhuo/sqlalchemy-fulltext-search), but since that I get unexpected results. When I run
nosetests -v
An OperationalError: (OperationalError) near "(": syntax error u'ALTER TABLE opportunity ADD FULLTEXT (title, content, requirements)' () comes out.
I'm defining fulltext_columns:
__fulltext_columns__ = ('title', 'content', 'requirements')
It looks like SQLAlchemy-FullText-Search does only work on MySQL databases - but the default test suite of a TurboGears 2 webapp is using an SQLite in-memory database, so that might be the problem.
I'm experiencing a strange bug with the way Django Test framework operates.
When using SQLite Database Backend, all of the tests crash with the following error:
File "[]/core/tests/test_admin.py", line 91, in setUpSomething
content_type = ContentType.objects.get(app_label='core', model='SomeModel')
File "[]/lib/python2.7/site-packages/django/db/models/manager.py", line 151, in get
return self.get_queryset().get(*args, **kwargs)
File "[]/lib/python2.7/site-packages/django/db/models/query.py", line 310, in get
self.model._meta.object_name)
DoesNotExist: ContentType matching query does not exist.
However, the same code executes well under MySQL backend.
Clearly Django should make these functions agnostic of the backend used?
I had the same problem and I have no idea if my solution will be helpful, but it solved my issue, so here goes.
In my application code, I was attempting to query ContentType instances in the following way:
email = ContentType.objects.get(app_label="users", model="EmailAddress")
This worked fine with our actual MySQL database, but failed in test under a SQLite test database. However, if I switched the model definition to lowercase, it worked in both places:
email = ContentType.objects.get(app_label="users", model="emailaddress")
My guess was that this may have to do with the default collation in MySQL of case-insensitivity, so the first query should not have worked if I were comparing case-sensitively.
Indeed, when I looked at my database, all the model labels in the django_content_type table were lowercase and SQLite cares (by default) about case, so my queries in my tests were legitimately failing.