zoukankan      html  css  js  c++  java
  • Django 使用 raw sql

    connections与connection

    db.connections是一个类似字典的对象,可以通过某个数据库连接的别名获取这个数据源的connection。比如connections['my_db_alias']

    from django.db import connections
    for key in connections:
        print(key)
    # 可以打印出所有配置了的数据源别名,django会为每个数据源创建一个connection
    

    通过django/db/init.py中

    class DefaultConnectionProxy:
        """
        Proxy for accessing the default DatabaseWrapper object's attributes. If you
        need to access the DatabaseWrapper object itself, use
        connections[DEFAULT_DB_ALIAS] instead.
        """
        def __getattr__(self, item):
            return getattr(connections[DEFAULT_DB_ALIAS], item)
    
        def __setattr__(self, name, value):
            return setattr(connections[DEFAULT_DB_ALIAS], name, value)
    
        def __delattr__(self, name):
            return delattr(connections[DEFAULT_DB_ALIAS], name)
    
        def __eq__(self, other):
            return connections[DEFAULT_DB_ALIAS] == other
    
    
    connection = DefaultConnectionProxy()
    

    由于DEFAULT_DB_ALIAS='default',可以知道from django.db import connection获取的就是connections['default']

    因此,在多数据库的情况下,可以通过connections获取特定数据库连接的queries或cursor

    from django.db import connections
    connections['my_db_alias'].queries
    cursor = connections['my_db_alias'].cursor()
    

    使用cursor跨库查询

    前面已经提到,使用connection.cursor()表示使用默认数据库的连接

    如果有多个数据库连接配置,那么一定要用connections[db_name].cursor()指定一个

    那么在connections[db_name].cursor()中可以查到另一个schema中的表吗?

    答案是可以的

    比如,我想要连接db_1的order表和db_2的product表,可以使用connections[db_1].cursor()进行连接,然后在sql中通过db_2.product访问db_2

    sql = "select o.id from order o, db_2.product p where o.product_id=p.id and p.type=%s"
    sql_values = [1]
    with connections["db_1"].cursor() as cur:
        cur.execute(sql, sql_values)
        order_ids = [row[0] for row in cur.fetchall()]
    

    前提是db_2与db_1在同一个MySQL的服务端上

    传递cursor参数

    cur.execute(sql, sql_values) 并不是简单的字符串拼接,它可以有效防止sql注入

    注意以下的写法是错误的

    # 直接使用字符串拼接
    >>> query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
    >>> Person.objects.raw(query)
    
    # 画蛇添足地使用'%s',不需要担心cursor识别不了字符串
    >>> query = "SELECT * FROM myapp_person WHERE last_name = '%s'"
    

    占位符对应的python数据类型可以是int、str、datetime、list等类型。这些类型在被整合进sql语句前都会得到正确的处理

    sql = (
    		"select * from product where "
       "created_time >= %s and type in %s and order_id = %s and device_name = %s"
    )
    cursor.execute(sql, [datetime.now(), [1,2], 123, "iphone"])
    

    参考文档

    https://docs.djangoproject.com/en/3.1/topics/db/sql/

  • 相关阅读:
    推自己的镜像到网易云
    supervisord常见问题
    supervisord的配置
    一文解读SDN (转)
    一文解读ZooKeeper (转)
    使用 Docker 和 Nginx 打造高性能的二维码服务 (转)
    一文解读Docker (转)
    一文解读分布式架构 (转)
    一文解读分布式事务 (转)
    一文读懂工业大数据 (转)
  • 原文地址:https://www.cnblogs.com/luozx207/p/13634423.html
Copyright © 2011-2022 走看看