我在我的SQLite數據庫中有6個表,每個表有6列(Date, user, NormalA, specialA, contact, remarks
)和1000+行。python sqlalchemy不同列值
如何使用sqlalchemy對日期列進行排序以查找重複的日期並刪除該行?
我在我的SQLite數據庫中有6個表,每個表有6列(Date, user, NormalA, specialA, contact, remarks
)和1000+行。python sqlalchemy不同列值
如何使用sqlalchemy對日期列進行排序以查找重複的日期並刪除該行?
由Find duplicate values in SQL table的啓發,這可能幫助您選擇重複日期:
query = session.query(
MyTable
).\
having(func.count(MyTable.date) > 1).\
group_by(MyTable.date).all()
如果你只想顯示獨特的日期; distinct on
是你可能需要的東西
不能做一個'func.count'。似乎沒有那個選擇 –
@jakewong你導入函數:'from sqlalchemy import func'? – Parfait
雖然我喜歡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' ;");
而且finnally保持第一插入的記錄並刪除最近的重複記錄:
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
假設這是你的模型:
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)
Q1:你還有一個單獨的主鍵列嗎? Q2:爲什麼你對這個問題有重要的** 6表格? – van