[英]python sqlalchemy distinct column values
我的SQLite數據庫中有6個表,每個表有6列( Date, user, NormalA, specialA, contact, remarks
)和1000多行。
如何使用sqlalchemy對Date列進行排序以查找重復日期,並刪除該行?
假設這是你的模型:
class MyTable(Base):
__tablename__ = 'my_table'
id = Column(Integer, primary_key=True)
date = Column(DateTime)
user = Column(String)
# do not really care of columns other than `id` and `date`
# important here is the fact that `id` is a PK
以下是兩種刪除數據的方法:
對於它們兩者,將使用輔助子查詢:
# helper subquery: find first row (by primary key) for each unique date
subq = (
session.query(MyTable.date, func.min(MyTable.id).label("min_id"))
.group_by(MyTable.date)
) .subquery('date_min_id')
選項-1:查找重復項,將其標記為刪除並提交事務
# query to find all duplicates
q_duplicates = (
session
.query(MyTable)
.join(subq, and_(
MyTable.date == subq.c.date,
MyTable.id != subq.c.min_id)
)
)
for x in q_duplicates:
print("Will delete %s" % x)
session.delete(x)
session.commit()
選項2:創建單個SQL查詢,直接在數據庫上執行刪除
sq = (
session
.query(MyTable.id)
.join(subq, and_(
MyTable.date == subq.c.date,
MyTable.id != subq.c.min_id)
)
).subquery("subq")
dq = (
session
.query(MyTable)
.filter(MyTable.id.in_(sq))
).delete(synchronize_session=False)
受SQL表中的查找重復值的啟發,這可能有助於您選擇重復日期:
query = session.query(
MyTable
).\
having(func.count(MyTable.date) > 1).\
group_by(MyTable.date).all()
如果您只想顯示獨特的日期; distinct on
是你可能需要的東西
雖然我喜歡使用SQLAlchemy的整個面向對象的方法,但有時我發現直接使用某些SQL更容易。 由於記錄沒有密鑰,我們需要行號( _ROWID_
)來刪除目標記錄,我認為API並不提供。
首先我們連接到數據庫:
from sqlalchemy import create_engine
db = create_engine(r'sqlite:///C:\temp\example.db')
eng = db.engine
然后列出所有記錄:
for row in eng.execute("SELECT * FROM TableA;") :
print row
並顯示日期相同的所有重復記錄:
for row in eng.execute("""
SELECT * FROM {table}
WHERE {field} IN (SELECT {field} FROM {table} GROUP BY {field} HAVING COUNT(*) > 1)
ORDER BY {field};
""".format(table="TableA", field="Date")) :
print row
現在我們確定了所有重復項,如果其他字段不同,則可能需要修復它們:
eng.execute("UPDATE TableA SET NormalA=18, specialA=20 WHERE Date = '2016-18-12' ;");
eng.execute("UPDATE TableA SET NormalA=4, specialA=8 WHERE Date = '2015-18-12' ;");
並最終保留第一個插入的記錄並刪除最新的重復記錄:
print eng.execute("""
DELETE FROM {table}
WHERE _ROWID_ NOT IN (SELECT MIN(_ROWID_) FROM {table} GROUP BY {field});
""".format(table="TableA", field="Date")).rowcount
或者保留最后插入的記錄並刪除其他重復記錄:
print eng.execute("""
DELETE FROM {table}
WHERE _ROWID_ NOT IN (SELECT MAX(_ROWID_) FROM {table} GROUP BY {field});
""".format(table="TableA", field="Date")).rowcount
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.