如何在每一条SQL前加一个统一的注释 #2200
Labels
No Label
backport/done
backport/v1
blocked
db
oracle
db
sqlserver
duplicate
feature
cache
frontport/done
frontport/main
invalid
kind
breaking
kind
bug
kind
build
kind
dependencies
kind
docs
kind
driver
kind
enhancement
kind
feature
kind
performance
kind
proposal
kind
question
kind
refactor
kind
testing
need
feedback
need
test
proposal:accepted
RaspBerry Pi
regression
skip-changelog
upstream
wip
wontfix
No Milestone
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: xorm/xorm#2200
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
比如proxysql之类一些mysql中间件对外只提供一个服务,中间件自己去处理读写分离。但当业务需要指定访问主库时需要在查询的前面增加一段注释,如
/*master*/ SELECT * FROM xxx
,现在通过SQL的方式可以手动拼,但是通过Find/Get之类的好像没有一个很好的办法,如果使用Hook.BeforeProcess处理,好像在处理Prepare的时候会有问题https://help.aliyun.com/document_detail/477438.html 比如这个
我们也正好碰到这个问题,需要在 SQL 执行之前对 SQL 改写(修改表名),让不同的租户执行不同的表;或者就是类似你想的,添加一个注释在最前面,然后让 proxy 去解析,解析完成之后进行处理。
然后,我们尝试了很多方式当下均无法实现,比如你说的使用
ContextHook
,但是ContextHook
中的 SQL 并不是最终执行的 SQL,它仅仅只是query
的一个复制而已。我们也尝试包装了一个新的Dialect
去替换已有的 mysql 的Dialect
,并且添加自定义的Filters
方法来返回过滤器来过滤 SQL,这个方法可以解析并改写 SQL,但问题是,Filter 的 接口是Do(sql string) string
无法获取到 context 也就是说无法获取到具体的用户信息(租户id),也就无法对它传递信息。所以,现在我们的解决方案是,修改源码中的 Filter 接口,对于
Do(sql string) string
添加 context 参数,将当前 session 的 context 传递进来,获取对应信息进行改写。不过,我们并不确定这个方案是否完美覆盖到所有场景,至少现在测试下来没有问题,SQL 可以被成功改写。@ssfyn 对于你的问题,或许,可能不需要像我们一样改写源码,只需要通过 Filter 识别到所需要查询主库的对应 SQL 加注释就可以了。
@lunny 你觉得对于
Filter
的Do
接口添加 context 是否为一种比较好的解决方案,如果可行,我可以提交一个 PR。或者说让 ContextHook 中的 sql 替换最终执行的 sql 更加友好呢?Filter 可以支持 context