用于测试环境的 Symfony 4 sqlite 数据库创建

Symfony 4 sqlite database creation for test environment

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

看起来它没有读取 env.test。

我在 config/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: {  }

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

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

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

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

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

因此 运行ning bin/console --env=test doctrine:schema:create 将尝试为 实体管理器 [=55= 的 ALL 创建模式] 出现在生成的配置中。

要解决此问题,您需要将环境配置分为 prodtestdev,或者使用 .env.test 更改交响乐。

取决于您访问实体管理器的方式

例子

This is only an example of how to segregate the environment configurations, be sure to change any needed values for your application requirements

config/packages/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

config/packages/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

config/packages/test/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)
     #...

config/packages/prod/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
     #...