编写MySQL Python类的最佳方法是什么?

2024-04-26 02:18:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在编写一个数据库类,其中有我需要的每个查询的方法。在

这样做,我得到了50多种方法。在

我认为我应该编写一个小类,包含选择、删除、更新、插入等方法,然后直接将查询写到我的方法中。在

哪种方式更好?为什么?我还有别的办法吗?在


Tags: 方法数据库方式办法小类
2条回答

为什么不使用查询生成器或ORM呢?https://github.com/kayak/pypika 使用查询生成器获取对查询的控制粒度,并为重复任务获取ORM。在

这确实适用于python和mysql之外的上下文:

您要问的是如何设计数据库适配器,即用于与数据库通信的代码。有许多重要问题需要考虑:

  1. 对底层数据库进行更改有多容易?你需要做很多代码修改吗?在
  2. 添加新查询有多容易?在
  3. 测试起来有多容易?在

为每个MySQL动词设置方法似乎很有吸引力,因为这样就不必为每个查询类型添加一个新方法,但好处就在这里了。您可能会开始将某些查询复制并粘贴到不同的位置。一旦发生这种情况,要更新查询中的任何内容(表名、列名、联接,甚至是它的工作方式的细节,可能是不同的排序顺序或限制),您必须在您复制到的每个位置修改查询。这很快就失控了。这也意味着你的控制器(假设你没有使用MVC,就把它们看作是调用你编写的这个DB包装器的代码)变成了底层DB实现的tightly coupled。这种脆性使它们更难测试。你需要设置一个数据库来测试它们。在

您当前为每种类型的查询提供方法的方法可能感觉像是更多的代码,但是您所近似的是Repository pattern。这里的想法是,我们将所有与数据库工作方式相关的行为(表名、列名、联接、外键、排序策略、缓存)抽象到几个特定的类中。对于博客文章,可能这是一个BlogPostRepository。对于注释,这可以是CommentRepository。他们会这样做:

class BlogPostRepository(Repository):
    def create(self, blog_post):
        with self._conn.cursor() as c:
            c.execute('INSERT ...', blog_post.name) # etc.

    def list(self):
        return [BlogPost(r) for r in self._conn.query('SELECT * FROM blog_post')]

现在,您的控制器只需将存储库作为一个arg来初始化(许多框架可以使用dependency injection)来简化这一点:

^{pr2}$

任何其他需要列出博客文章的地方都可以使用相同的代码。随后,如果需要更改列出博客文章的工作方式,只需修改BlogPostRepository中的代码。另外,在测试控制器时,可以传入模拟存储库并断言调用了正确的方法。这样,控制器测试不需要设置数据库(如果更改了数据库,这些测试也需要更改)。在

如果编写SQL查询变得很麻烦,或者您想防止需要更改底层数据库的情况,可以查看ORM。但是如果您选择使用一个,您仍然应该将ORM的使用包装在存储库模式中,这样您的控制器就不会与数据库代码紧密耦合。在

相关问题 更多 >