symfony 2/3应用程序中的多个连接和实体管理器

时间:2016-09-23 09:40:02

标签: php doctrine symfony multi-tenant

我的多租户应用程序使用主数据库,该数据库包含有关租户的信息(如姓名等)和特定于应用程序的数据库每个租户

我在config.yml中的doctrine部分配置了 some_tenant 连接和实体管理器。

这使我可以从控制器访问主数据库(例如,根据子域验证和获取 some_tenant 的租户信息 some_tenant.my-app.com )。它允许我在应用程序生命周期中使用特定于租户的数据库和实体管理器。

我的配置中的学说部分如下所示:

doctrine:
dbal:
    default_connection: 'master'
    connections:
        master:
            driver:   pdo_mysql
            host:     "%database_host%"
            port:     "%database_port%"
            dbname:   "%database_name%"
            user:     "%database_user%"
            password: "%database_password%"
            charset:  UTF8
        some_tenant:
            driver:   pdo_mysql
            host:     "%database_host_some_tenant%"
            port:     "%database_port_some_tenant%"
            dbname:   "%database_name_some_tenant%"
            user:     "%database_user_some_tenant%"
            password: "%database_password_some_tenant%"
            charset:  UTF8

orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    entity_managers:
        master:
            connection: master
            mappings:
                BEMultiTenancyBundle: ~
        some_tenant:
            connection: some_tenant
            mappings:
                AppBundle: ~

这部分是我不满意的部分,无法找到解决方案:

首先,租户将超过20个。它开始变得混乱,以这种方式改变学说配置。 然后还有另一个名为tenants.yml的配置文件,其中包含更多信息,如启用/禁用的应用程序功能,特定于租户的主题等。

使用Config Component加载,验证文件,并设置容器参数,以便应用程序范围内的租户配置可用。 我想将数据库凭据也存储在该文件中。

  1. 我想基于该配置创建连接和实体管理器。每个租户一个,可以在应用程序生命周期中使用。

  2. 我还需要在控制台命令bin/console doctrine:schema:update --em=some_tenant上使用它们来更新每个租户的数据库模式,并bin/console doctrine:schema:update --em=master更新主数据库方案。

  3. 到目前为止,我想,实现这一目标的唯一方法是在加载AppBundle之后以编程方式 添加配置参数,然后 之前由给定的管理者和关系构建。

    但我甚至无法找到一个观点,我可以在这里找到答案。

    还有另一种方法可以到达第1点和第2点吗?

    即使有一个similiar question,我不确定它是否完全是同一个问题并且大约有3年了,我想更多地解释一下这个问题。

2 个答案:

答案 0 :(得分:1)

评论中的解决方案是一种简单易用的解决方案,它将起作用。我遇到的另一个解决方案是使用一些外部条件动态替换租户数据库凭证,即请求HOST

您可以通过某种方式装饰或扩展连接工厂,使请求堆栈可用(或为其他SAPI提供ENV或控制台参数的域),您可以拥有相同的实体管理器(甚至{{1按需配置。

简要来看,这看起来像

default

答案 1 :(得分:0)

我认为,用symfony 2/3来管理多租户。 我们可以为ORM的学说配置auto_mapping: false。 file:config.yml

doctrine:
    dbal:
        default_connection: master
        connections:
            master:
                driver:   pdo_mysql
                host:     '%master_database_host%'
                port:     '%master_database_port%'
                dbname:   '%master_database_name%'
                user:     '%master_database_user%'
                password: '%master_database_password%'
                charset:  UTF8
            tenant:
                driver:   pdo_mysql
                host:     '%tenant_database_host%'
                port:     '%tenant_database_port%'
                dbname:   '%tenant_database_name%'
                user:     '%tenant_database_user%'
                password: '%tenant_database_password%'
                charset:  UTF8

    orm:
        default_entity_manager: master
        auto_generate_proxy_classes: "%kernel.debug%"
        entity_managers:
            master:
                connection: master
                auto_mapping: false
                mappings:
                    AppBundle:
                        type: yml
                        dir: Resources/master/config/doctrine
            tenant:
                connection: tenant
                auto_mapping: false
                mappings:
                    AppBundle:
                        type: yml
                        dir: Resources/tenant/config/doctrine

之后,我们无法通过request_listener中的覆盖连接信息来处理每个租户的连接,例如文章:http://mohdhallal.github.io/blog/2014/09/12/handling-multiple-entity-managers-in-doctrine-the-smart-way/ 我希望,这种做法可以帮助那些与多租户合作的人

此致 Vuong Nguyen