首页 > 解决方案 > 用于测试环境的 Symfony 4 sqlite 数据库创建

问题描述

出于集成测试的目的,我正在尝试为测试环境创建一个 sqlite db,但是当我运行时,php bin/console doctrine:schema:create --env=test我收到表已经存在的错误。我想是因为它并没有真正创建一个新的测试数据库,而是继续现有的数据库。

看起来它不是从 env.test 中读取的。

doctrine.yaml在配置/测试中创建了一个这样的:

doctrine:
dbal:
    driver: 'pdo_sqlite'
    url: 'sqlite:///%kernel.project_dir%/var/data/test.sqlite'

创建sqlite测试数据库我缺少什么?

我在错误中得到奇怪的东西:

In PDOConnection.php line 90:

 SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'user_menu' already exists 

为什么是 SQL?不应该是 SQLite 的 IT,对吗?

在 config/packages/doctrine.yaml 中,我有:

parameters:
# Adds a fallback DATABASE_URL if the env var is not set.
# This allows you to run cache:warmup even if your
# environment variables are not available yet.
# You should not need to change this value.
env(DATABASE_URL): ''

doctrine:
dbal:
    # configure these for your database server
    connections:
            gui:
                driver: 'pdo_mysql'
                server_version: '5.7'
                charset: utf8mb4
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                url: '%env(resolve:DATABASE_GUI_URL)%'
            upv6:
                driver: 'pdo_mysql'
                server_version: '5.7'
                charset: utf8mb4
                default_table_options:
                    charset: utf8mb4
                    collate: utf8mb4_unicode_ci
                url: '%env(resolve:DATABASE_UPV6_URL)%'
orm:
    auto_generate_proxy_classes:  true # <- change to true
    proxy_dir:            '%kernel.cache_dir%/doctrine/orm/Proxies'
    proxy_namespace:      Proxies

    entity_managers:
        gui:
            connection: gui
            mappings:
                Gui:
                    is_bundle: false
                    type: annotation
                    dir: '%kernel.project_dir%/src/Entity/Gui'
                    prefix: 'App\Entity\Gui'
                    alias: Gui
        upv6:
            connection: upv6
            mappings:
                Upv6:
                    is_bundle: false
                    type: annotation
                    dir: '%kernel.project_dir%/src/Entity/Upv6'
                    prefix: 'App\Entity\Upv6'
                    alias: Upv6

我的学说设置:

doctrine:
dbal:
    connections:
        gui:
            driver: pdo_mysql
            server_version: '5.7'
            charset: utf8mb4
            default_table_options:
                charset: utf8mb4
                collate: utf8mb4_unicode_ci
            url: '%env(resolve:DATABASE_GUI_URL)%'
            host: localhost
            port: null
            user: root
            password: null
            logging: true
            profiling: true
            options: {  }
            mapping_types: {  }
            slaves: {  }
            shards: {  }
        upv6:
            driver: pdo_mysql
            server_version: '5.7'
            charset: utf8mb4
            default_table_options:
                charset: utf8mb4
                collate: utf8mb4_unicode_ci
            url: '%env(resolve:DATABASE_UPV6_URL)%'
            host: localhost
            port: null
            user: root
            password: null
            logging: true
            profiling: true
            options: {  }
            mapping_types: {  }
            slaves: {  }
            shards: {  }
        default:
            driver: pdo_sqlite
            url: '%env(resolve:DATABASE_URL)%'
            host: localhost
            port: null
            user: root
            password: null
            logging: true
            profiling: true
            options: {  }
            mapping_types: {  }
            default_table_options: {  }
            slaves: {  }
            shards: {  }
    default_connection: default
    types: {  }
orm:
    auto_generate_proxy_classes: true
    proxy_dir: /var/www/symfony/var/cache/test/doctrine/orm/Proxies
    proxy_namespace: Proxies
    entity_managers:
        gui:
            connection: gui
            mappings:
                Gui:
                    is_bundle: false
                    type: annotation
                    dir: /var/www/symfony/src/Entity/Gui
                    prefix: App\Entity\Gui
                    alias: Gui
                    mapping: true
            query_cache_driver:
                type: array
                namespace: null
                cache_provider: null
            metadata_cache_driver:
                type: array
                namespace: null
                cache_provider: null
            result_cache_driver:
                type: array
                namespace: null
                cache_provider: null
            class_metadata_factory_name: Doctrine\ORM\Mapping\ClassMetadataFactory
            default_repository_class: Doctrine\ORM\EntityRepository
            auto_mapping: false
            naming_strategy: doctrine.orm.naming_strategy.default
            quote_strategy: doctrine.orm.quote_strategy.default
            entity_listener_resolver: null
            repository_factory: doctrine.orm.container_repository_factory
            hydrators: {  }
            filters: {  }
        upv6:
            connection: upv6
            mappings:
                Upv6:
                    is_bundle: false
                    type: annotation
                    dir: /var/www/symfony/src/Entity/Upv6
                    prefix: App\Entity\Upv6
                    alias: Upv6
                    mapping: true
            query_cache_driver:
                type: array
                namespace: null
                cache_provider: null
            metadata_cache_driver:
                type: array
                namespace: null
                cache_provider: null
            result_cache_driver:
                type: array
                namespace: null
                cache_provider: null
            class_metadata_factory_name: Doctrine\ORM\Mapping\ClassMetadataFactory
            default_repository_class: Doctrine\ORM\EntityRepository
            auto_mapping: false
            naming_strategy: doctrine.orm.naming_strategy.default
            quote_strategy: doctrine.orm.quote_strategy.default
            entity_listener_resolver: null
            repository_factory: doctrine.orm.container_repository_factory
            hydrators: {  }
            filters: {  }
    resolve_target_entities: {  }

标签: phpsymfonysymfony4

解决方案


这个问题是由 Symfony 合并配置文件的方式引起的。

/config/packages/*.yml>/config/packages/<env>/*.yml

这会导致将定义的所有连接和实体管理器packages/doctrine.yml添加到您的packages/test/doctrine.yml

要查看 Symfony 将使用的合并配置设置,请运行:

php bin/console --env=test debug:config doctrine

由于此运行bin/console --env=test doctrine:schema:create将尝试为结果配置中存在的所有实体管理器创建模式。

要解决此问题,您需要将您的环境配置分隔为prodtestdev/或.env.test用于更改 Syfmony 使用的 URL。

取决于您需要如何访问您的实体管理器

例子

这只是如何隔离环境配置的示例,请务必根据您的应用程序要求更改任何所需的值

配置/包/doctrine.yml

parameters:
    # Adds a fallback DATABASE_URL if the env var is not set.
    # This allows you to run cache:warmup even if your
    # environment variables are not available yet.
    # You should not need to change this value.
    env(DATABASE_URL): ''

doctrine:
    orm:
        auto_generate_proxy_classes:  true # <- change to true
        proxy_dir:            '%kernel.cache_dir%/doctrine/orm/Proxies'
        proxy_namespace:      Proxies

配置/包/dev/doctrine.yml

doctrine:
    dbal:
        # configure these for your database server
        connections:
                gui:
                    driver: 'pdo_mysql'
                    server_version: '5.7'
                    charset: utf8mb4
                    default_table_options:
                        charset: utf8mb4
                        collate: utf8mb4_unicode_ci
                    url: '%env(resolve:DATABASE_GUI_URL)%'
                upv6:
                    driver: 'pdo_mysql'
                    server_version: '5.7'
                    charset: utf8mb4
                    default_table_options:
                        charset: utf8mb4
                        collate: utf8mb4_unicode_ci
                    url: '%env(resolve:DATABASE_UPV6_URL)%'        
        entity_managers:
            gui:
                connection: gui
                mappings:
                    Gui:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/Gui'
                        prefix: 'App\Entity\Gui'
                        alias: Gui
            upv6:
                connection: upv6
                mappings:
                    Upv6:
                        is_bundle: false
                        type: annotation
                        dir: '%kernel.project_dir%/src/Entity/Upv6'
                        prefix: 'App\Entity\Upv6'
                        alias: Upv6

配置/包/测试/doctrine.yml

doctrine:
    dbal:
        driver: 'pdo_sqlite'
        url: 'sqlite:///%kernel.project_dir%/var/data/test.sqlite'

    #DEFINE THE ENTITY MANAGERS TO USE THE default CONNECTION
    #orm:
        #since the connections are not the same
        #you need to define your entity managers here...
        #entity_managers:
     #      gui:
     #          connection: default #<---- NOTICE DEFAULT and not gui 
     # (not sure what entity managers are needed for sqlite)
     #...

配置/包/产品/doctrine.yml

imports:
    - { resource: '../dev/doctrine.yaml' }

doctrine:
    orm:
        auto_generate_proxy_classes: false #<-- change to false
        metadata_cache_driver:
            type: service
            id: doctrine.system_cache_provider
        query_cache_driver:
            type: service
            id: doctrine.system_cache_provider
        result_cache_driver:
            type: service
            id: doctrine.result_cache_provider
     #...

推荐阅读