# How to pass list of integers as arguments for django's raw SQL, without formatting string

**URL:** <https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857>\
**Category:** Using the ORM\
**Created:** [July 10, 2024, 12:11pm UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857 "2024-07-10T12:11:48Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Atidhaya](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/atidhaya/32/22513_2.png) [@Atidhaya](https://forum.djangoproject.com/u/Atidhaya)\
**Post date:** [July 10, 2024, 12:11pm UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857/1 "2024-07-10T12:11:48Z")

</div>

I’m struggling to figure out how to pass list of integer as arguments for Django’s raw SQL without using f-string method.

I have tried a simple method of

```auto
def raw_query(self) -> str:
    return """select * from table where some_id in %s"""

```

and call with (where ids are list of integer that I already wrap them as tuple)

```auto
tupled_ids = tuple(ids)
with connection.cursor() as cursor:
    cursor.execute(self.raw_query(), [ids])

```

Apparently, this wraps the argument with single quote, making them ‘(1,2,3)’ instead of (1,2,3). Thus, syntax error.

```auto
django.db.utils.ProgrammingError: syntax error at or near "'(1,2,3)'"

```

I’ve also tried

```auto
def raw_query(self) -> str:
    return """select * from table where some_id = any(%s)"""

```

also give me similar error

```auto
django.db.utils.DataError: malformed array literal: "(1,2,3,4,5)"
LINE 2: ...om table where some_id = any('(1,2,3...`

```

I’ve also tried with named params

```auto
def raw_query(self) -> str:
    return """select * from table where some_id in %(ids)s"""

```

```auto
with connection.cursor() as cursor:
    cursor.execute(sql=self.raw_query(),
                           params={
                               "ids": tuple(ids)
                           })

```

Still produce syntax error.

Looks like django keep wrapping my list with quote. I feel like there must have been an obvious mistake but I can’t really figure it out.

There are other solutions that suggest to generate a place holder and use f-string to format the raw SQL statement, such as.

```auto
def raw_query(self, ids: list[int]) -> str:
    placeholder = ','.join(['%s'] * len(ids))
    return f"""select * from table where some_id in ({placeholders})"""

```

^ This works

Still, I am wondering if there’s a better solution as I don’t want to string format my SQL statement.

Any help is gladly appreciated.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [July 11, 2024, 1:58am UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857/2 "2024-07-11T01:58:40Z")

</div>

It works for me if I pass the list directly.  
e.g.:

```auto
In [25]: ids = (1,2,3)

In [26]: cursor = connection.cursor()

In [27]: cursor.execute("select * from auth_user where id in %s", [idl])

In [28]: data = cursor.fetchall()

In [29]: print(len(data))
3

```

Is it possible that `ids` isn’t what you think it is at this point?

---

<div class="post-metadata">

**Author:** ![Atidhaya](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/atidhaya/32/22513_2.png) [@Atidhaya](https://forum.djangoproject.com/u/Atidhaya)\
**Post date:** [July 11, 2024, 3:31am UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857/3 "2024-07-11T03:31:48Z")

</div>

> [@KenWhitesell](#):
>
> `data = cursor.fetchall()`

Unfortunately no, I try with your example, I also got error. Perhaps I’m using the wrong package? but last I check from documentation it’s `from django.db import connection`

I’m on django 5.0.6 and postgresql if that matters

 ![Screenshot 2567-07-11 at 10.29.56](https://us1.discourse-cdn.com/flex026/uploads/djangoproject/original/3X/1/2/126514e7237cd4146d3ac9d1f55ca9e7cf30a1f7.png)

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [July 11, 2024, 12:09pm UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857/4 "2024-07-11T12:09:46Z")

</div>

What version of psycopg do you have installed? (I also use PostgreSQL)

---

<div class="post-metadata">

**Author:** ![Atidhaya](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/atidhaya/32/22513_2.png) [@Atidhaya](https://forum.djangoproject.com/u/Atidhaya)\
**Post date:** [July 11, 2024, 2:13pm UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857/5 "2024-07-11T14:13:53Z")

</div>

Thank you for your time, I just want to let you know I really appreciated your help so far!

I’m using 3.2.1 😅

```auto
poetry show | grep psycopg
psycopg 3.2.1 PostgreSQL database adapter ...
psycopg-binary 3.2.1 PostgreSQL database adapter ...

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [July 11, 2024, 3:19pm UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857/6 "2024-07-11T15:19:12Z")

</div>

This is a difference between psycopg2 and psycopg 3.

See the docs at [Differences from psycopg2 - psycopg 3.2.2.dev1 documentation](https://www.psycopg.org/psycopg3/docs/basic/from_pg2.html) for some options here. (I’ve tried a couple of them and they do work - I’m just not sure whether they’re as secure as the original for your use-case - I’m no expert on creating SQL injection exploits.)

---

<div class="post-metadata">

**Author:** ![Atidhaya](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/atidhaya/32/22513_2.png) [@Atidhaya](https://forum.djangoproject.com/u/Atidhaya)\
**Post date:** [July 11, 2024, 4:00pm UTC](https://forum.djangoproject.com/t/how-to-pass-list-of-integers-as-arguments-for-djangos-raw-sql-without-formatting-string/32857/7 "2024-07-11T16:00:03Z")

</div>

It works perfectly, thank you!
