Symfony2 and sqlite, SQLSTATE[HY000] caught - sqlite

I'm trying to use sqlite3 with symfony2.
This is my database configuration in app/config/parameters.yml
parameters:
database_driver: pdo_sqlite
database_host: 127.0.0.1
database_port: null
database_name: librarian
database_user: root
database_password: null
database_path: librarian
And my app/config/config.yml
# Doctrine Configuration
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
path: %kernel.root_dir%/%database_path%.db
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: true
I've created a simple table to do some test. This table have an integer auto-increment 'id' field, a 'link' text field and a 'index' integer field.
The controller is simple :
class testController extends Controller {
public function indexAction() {
$issue = new Issue();
$issue->setIndex(0);
$issue->setLink(array('http://example.com'));
$em = $this->getDoctrine()->getManager();
$em->persist($issue);
$em->flush();
return $this->render('TestLibrarianBundle:Test:index.html.twig');
}
}
When I try to get execute the request by calling this controller, I got the following error:
request.CRITICAL: Uncaught PHP Exception Doctrine\DBAL\DBALException: "An exception occurred while executing 'INSERT INTO issue (index, link) VALUES (?, ?)':
SQLSTATE[HY000]: General error: 1 near "index": syntax error" at /.../.../vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php line 47
Any hint on how to solve this ?
Thanks

Can you name a field index if it's a sqlite keyword?

Your problem is that INDEX is an SQL keyword.
If you cannot configure your ORM to escape names properly (writing them as "index" instead), you have to change the field name to something else.

Related

Symfony 2.8 two database connections

I need to connect to an external database, I just need to do a simple query in one table so I think I dont need to create an new entity manager. I believe all configurations are set up correctly but I still don't get connected to the new database. So i´m missing something but cant find what, here are my files:
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.root_dir%/data/data.db3'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
database2:
driver: pdo_mysql
host: '%database2_host%'
port: '%database2_port%'
dbname: '%database2_name%'
user: '%database2_user%'
password: '%database2_password%'
charset: UTF8
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
parameters:
#Set_Goals Database
database_host: 127.0.0.1
database_port: null
database_name: set_goals
database_user: root
database_password: null
#Database2 Database
database2_host: 127.0.0.1
database2_port: null
database2_name: second
database2_user: root
database2_password: null
Repository:
public function getAccounts(){
$conn = $this->getEntityManager()->getConnection('database2');
$sql = 'SELECT * FROM leme_account';
$stmt = $conn->prepare($sql);
$stmt->execute();
return $stmt->fetchAll();
}
Error:
An exception occurred while executing 'SELECT * FROM leme_account':
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'set_goals.leme_account' doesn't exist
set_goals database is the default connection.
Thanks in advance and sorry if I´m missing something really simple here but I´m new to Symfony and programming in general and I followed the documentation and also some related questions here but can´t make it work.
I think you need to create another entity manager
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.root_dir%/data/data.db3'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
database2:
driver: pdo_mysql
host: '%database2_host%'
port: '%database2_port%'
dbname: '%database2_name%'
user: '%database2_user%'
password: '%database2_password%'
charset: UTF8
orm:
auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
default_entity_manager: default
entity_managers:
default:
connection: default
database2:
connection: database2
Then in your code
$em = $this->get('doctrine')->getManager();
$em2 = $this->get('doctrine')->getManager('database2');
The documentation mentions a mappings key but I don't know if it is mandatory, especially since you are using auto mapping.
Ref: https://symfony.com/doc/2.8/doctrine/multiple_entity_managers.html
Meanwhile, I found the problem.... it was a newb mistake. I was putting my method inside the repository of the other entity. When I added directly to the controller it worked.
Thanks for your answers.

Multiple Entity Managers not working Symfony 3

I want to use multiple entity manager but it is not working.
config.yml
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
abc_1819:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name1819%'
user: '%database_user%'
password: '%database_password%'
charset: UTF8
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
AppBundle: ~
abc_1819:
connection: abc_1819
mappings:
Units:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/AppBundle/Entity'
prefix: 'AppBundle\Entity\Units'
If i use doctrine commands
php bin/console doctrine:database:create
php bin/console doctrine:database:create --connection=abc_1819
php bin/console doctrine:schema:update --force
php bin/console doctrine:schema:update --force --em=abc_1819
it working fine and create the database and table
UnitsController
In the controller default manager working by all methods
$entityManager = $this->getDoctrine()->getManager();
$entityManager = $this->getDoctrine()->getManager('default');
$entityManager = $this->get('doctrine.orm.default_entity_manager');
but the abc_1819 manager not working by using any of methods
$entityManager = $this->getDoctrine()->getManager('abc_1819');
$entityManager = $this->get('doctrine.orm.abc_1819_entity_manager');
it show the following error why ?
Oops! An Error Occurred
The server returned a "500 Internal Server Error".
Something is broken. Please let us know what you were doing when this error occurred. We will fix it as soon as possible. Sorry for any inconvenience caused.
I find the issue when i run project using
php bin/console server:run
it is working fine
But when i try to use http://localhost/abc/web/units/ then its not working

Symfony 3 - "Class was not found in the chain configured namespaces" when trying to build a relationship between two entities of two bundles

Using Symfony 3.4.2 , I am trying to build a relationship between two entities of two different bundles which uses their own databases located on different servers.
In other words, we have two databases, and then two entities managers :
One existing MariaDB database [person] which store one "person" table, used by many other applications.
One new MariaDB database [app] dedicated for the application.
Note that I can't change anything on that situation (legacy applications must still running). Althought it is planned "in the future" to replace the [person] database by a REST Api.
Following the Symfony doc (https://symfony.com/doc/3.4/doctrine/multiple_entity_managers.html), this gives the following app/config/config.yml file :
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
framework:
#esi: ~
#translator: { fallbacks: ['%locale%'] }
secret: '%secret%'
router:
resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
default_locale: '%locale%'
trusted_hosts: ~
session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~
http_method_override: true
assets: ~
php_errors:
log: true
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: '%database_host%'
port: '%database_port%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
# charset: UTF8
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
acme_another_db :
driver: pdo_mysql
host: '%acme_another_database_host%'
port: '%acme_another_database_port%'
dbname: '%acme_another_database_name%'
user: '%acme_another_database_user%'
password: '%acme_another_database_password%'
# charset: UTF8
charset: utf8mb4
default_table_options:
charset: utf8mb4
collate: utf8mb4_unicode_ci
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
#path: '%database_path%'
orm:
# Let's disable auto_mapping since we have several entity_managers
# auto_mapping: true
default_entity_manager: default
entity_managers:
default:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: default
mappings:
AppBundle: ~
acme_another_em:
naming_strategy: doctrine.orm.naming_strategy.underscore
connection: acme_another_db
mappings:
AcmeAnotherBundle: ~
auto_generate_proxy_classes: '%kernel.debug%'
# Swiftmailer Configuration
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
Since the "person" table is to be used by many other applications, I choosed to create a separate bundle.
In terms of entity, I have then 3 entities :
Acme/AnotherBundle/Entity/Person
AppBundle/Entity/Book
AppBundle/Entity/BookInterest
The first entity was generated without any error.
The AppBundle/Entity/Book and AppBundle/Entity/BookInterest entities were generated via bin\console generate:doctrine:entity without any problem.
Before updating the database schema, I added the relationship in the AppBundle/Entity/BookInterest entity class file (relation to Acme/AnotherBundle/Entity/Person and to AppBundle/Entity/Book), following the Symfony doc (http://symfony.com/doc/3.4/doctrine/associations.html).
/**
* #ORM\ManyToOne(targetEntity="Book", inversedBy="book")
* #ORM\JoinColumn(name="fk_book_id", referencedColumnName="id", nullable=false)
*/
private $book;
/**
* #ORM\ManyToOne(targetEntity="Acme\AnotherBundle\Entity\Person")
* #ORM\JoinColumn(name="fk_person_id", nullable=false)
*/
private $person;
But, when I try to update the schema via bin\console doctrine:schema:update --force --em=default, I have the following error message :
In MappingException.php line 37: The class
'Acme\AnotherBundle\Entity\Person' was not found in the chain
configured namespaces AppBundle\Entity
Adding "use Acme\AnotherBundle\Entity\Person;" in the top of \src\AppBundle\Entity\BookInterest.php and clearing the cache via bin\console cache:clear does not solve the problem.
Did I miss something in the app/config/config.yml configuration file, or in the \src\AppBundle\Entity\BookInterest.php entity class file ?
Doctrine2 unable to handle one relationship between two entity managers ?
I also found a (quite old) post on a similar problem (Using Relationships with Multiple Entity Managers), which indicates that Doctrine2 is unable to do that (due to the use of two entity managers).
If this is still the case, what is the best way to handle that situation ?
Is using one simple integer field without relation in the AppBundle/Entity/BookInterest for storing person_id and create manuals validation checks (then manual queries) in the BookInterestController is a good practice ?
Thanks a lot in advance for any tips (and good practice advices) to solve that case ! :-)

How to create a Second database connection with Symfony2?

I'm trying to connect a second database to my project in Symfony2. First, I added into parameters.yml some parameters to create the connection.
Then, I edited my config.yml, and now looks like:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
circutor3:
driver: pdo_sqlsrv
host: "%database_host_circutor3%"
port: "%database_port_circutor%"
dbname: "%database_name_circutor%"
user: "%database_user_circutor3%"
password: "%database_password_circutor3%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
Finally, I tried to get connected, using the following code in my controller:
$em = $this->getDoctrine()->getManager('circutor3');
And, the error returned by Symfony2:
Doctrine ORM Manager named "circutor3" does not exist.
The circutor3 makes connection to a database, external to my system, so I don't need to create entities or objects. I only need to execute some SELECT to get information and store it using an array.
Is creating a typical mysqli connection the best way to solve my problem?
I don't know how to solve this with Symfony.
Thank you in advance.
you could access to the database connection in the controller as follow:
$connection = $this->getDoctrine()->getConnection('circutor3');
then use the connection as:
$stmt = $connection->prepare($sql);
$stmt->execute();
return $stmt->fetchAll();
Some help here and here
Hope this help
According to Symfony documentation (http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html), you only defined a connection, not an entity manager :
You have to create an entity_manager for each connection.
orm:
default_entity_manager: default
entity_managers:
default:
...
circutor3:
connection: circutor3
mappings:
AppBundle: ~

Symfony2 and Doctrine APC Cache

i have read the documentation of symfony2 in relation to the performance and I have realized the following steps.
Install APC 'php-apc' on my webserver and restart my webserver
Modify my doctrine configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
auto_mapping: true
metadata_cache_driver: apc
result_cache_driver: apc
query_cache_driver: apc
Now if i call a action to retrieve all users from database i see in the information bar at the bottom that doctrine execute every time 114 queries. Why the queries not cached?
My action look like this:
$users = $this->getDoctrine()->getRepository('AppUserBundle:User')->findAll();
return $this->render('AppUserBundle:User:index.html.twig', array('users' => $users));
Doctrine doesn't cache query results by default. You have to explicitly point that you want to cache query using useResultCache method. For example, if you'd like to cache getting all users, write your own method in User repository class:
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
public function fetchAll()
{
$query = $this->createQueryBuilder('u')->getQuery();
return $query->useResultCache(true)->getResult();
}
}
The method may take additional arguments:
public function useResultCache($bool, $lifetime = null, $resultCacheId = null)
$bool - set to true if you want to cache query result
$lifetime - TTL of cached result in seconds
$resultCacheId - you can pass your own id, in case of null Doctrine will handle that

Resources