在Django中创建只读的MySQL数据库连接

12

是否可以添加一个连接到数据库,以便在使用它时只允许选择查询?

像这样的东西会很棒:

DATABASES = {
    #can do update, insert, etc...
    'default': { 
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'root',
        'PASSWORD': '12345',
    }
    #select only
    'default_readonly': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb',
        'PASSWORD': '12345',
        'READONLY': True,

    }
}

我没有找到任何简单的东西。

4个回答

7
据我所知,Django没有提供任何选项来限制数据库连接到“只读”模式。但是,您可以通过在MySQL数据库引擎中创建一个只读用户来实现它。
另一个想法是,在Django代码端创建自己的游标,如果调用了executeexecutemany则抛出异常。您可以查看这个模块django-db-readonly

5

从Django 1.2开始,您可以指定一个Router类将查询路由到不同的数据库(https://docs.djangoproject.com/en/dev/topics/db/multi-db/)。

要使用一个用于读取和一个用于写入的数据库,您可以定义以下Router类:

Class MyRouter(object):
    def db_for_read(self, model, **hints):
        return 'default_readonly'

    def db_for_write(self, model, **hints):
        return 'default'

    def allow_syncdb(self, db, model):
        return db == 'default'

将以下代码放置在您的settings.py文件中:

DATABASE_ROUTERS = ['path.to.MyRouter']

只要我不使用select_for_update(),这对我来说是有效的,因为它被认为是读操作,但需要写访问数据库。到目前为止,我找到的唯一解决方法是以类似的方式在Manager类中覆盖select_for_update:
class MyManager(Manager):

    def select_for_update(self, *args, **kwargs):
        return super(MyManager, self).using('default').select_for_update(*args, **kwargs)

实际上,我注意到在Django 1.7中,通过将select_for_update视为写操作来解决了该问题。 - Oberix

5

您应该在用于连接的用户上设置权限(而不是'root')。

这会导致插入/更新/删除查询引发错误,您应该在视图中管理这些错误(如果需要)。


1
谢谢Don!不过我更喜欢Maxime的解决方案,因为它让我保持在Django内部(因此也在Git内部)。 - YardenST

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接