[英]Filter with Array column with Postgres and SQLAlchemy
我有一个带有 int[] 列的简单表,我希望能够选择其中任何一个数组元素与我拥有的值相匹配的行,而且我无法弄清楚如何使用 SQLAlchemy 来做到这一点,而不仅仅是使用原始查询,我不想这样做。
这是表的架构(“testuser”):
Column | Type |
---------+------------------------+
id | integer |
name | character varying(250) |
numbers | integer[] |
下面是示例数据的样子:
id | name | numbers
----+---------+---------------
1 | David | {25,33,42,55}
2 | Salazar | {11,33,7,19}
3 | Belinda | {32,6,20,23}
4 | Casey | {19,20,27,8}
5 | Kathie | {25,31,10,40}
6 | Dianne | {25,20,40,39}
7 | Cortez | {1,20,18,38}
这是一个生成我想要的 SQL 语句; 我想在 Python 中完成这一切,而不是简单地编写原始查询(仅以 25 为例)。
scrape=# select * from testuser where 25 = ANY(numbers);
id | name | numbers
----+--------+---------------
5 | Kathie | {25,31,10,40}
6 | Dianne | {25,20,40,39}
1 | David | {25,33,42,55}
(3 rows)
我发现的另一种写法:
scrape=# select * from testuser where numbers @> ARRAY[25];
id | name | numbers
----+--------+---------------
5 | Kathie | {25,31,10,40}
6 | Dianne | {25,20,40,39}
1 | David | {25,33,42,55}
(3 rows)
这是我用来生成表的 Python 代码:
from sqlalchemy import Column, Integer, String
from sqlalchemy.dialects import postgresql
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class TestUser(Base):
__tablename__ = 'testuser'
id = Column(Integer, primary_key=True)
name = Column(String(250))
numbers = Column(postgresql.ARRAY(Integer))
engine = create_engine('postgresql://postgres:{pw}@localhost:5432/scrape'.format(pw=POSTGRES_PASSWORD))
Base.metadata.create_all(engine)
DBSession = sessionmaker(bind=engine)
session = DBSession()
testcases = [{"numbers": [25, 33, 42, 55], "name": "David"}, {"numbers": [11, 33, 7, 19 ], "name": "Salazar"}, {"numbers": [32, 6, 20, 23 ], "name": "Belinda"}, {"numbers": [19, 20, 27, 8 ], "name": "Casey"}, {"numbers": [25, 31, 10, 40 ], "name": "Kathie"}, {"numbers": [25, 20, 40, 39 ], "name": "Dianne"}, {"numbers": [1, 20, 18, 38 ], "name": "Cortez"} ]
for t in testcases:
session.add(TestUser(name=t['name'], numbers=t['numbers']))
session.commit()
所以你想使用 Postgres Array Comparator 。
query = session.query(TestUser).filter(TestUser.numbers.contains([some_int])).all()
或者
query = session.query(TestUser).filter(TestUser.numbers.any(25)).all()
该死的SQLAlchemy,我花了一些时间才弄清楚正确的方法是:
TelegramUser.query.filter(TelegramUser.selected_exchanges.contains(f"{{{platform_name}}}")).all()
其中platform_name
是str
并且selected_exchanges
列定义如下:
from sqlalchemy.dialects import postgresql as pg
selected_exchanges = db.Column(pg.ARRAY(db.String, dimensions=1), nullable=True)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.