Python中如何编写SQL语句?

A 表是主表,运行时如果有问题就把 A 表出问题的记录 ID 保存到 log 表中,等到全都运行完了后,再从 log 表中取出出问题的 ID 重新执行。 就是这最后一步的 sql 语句不会写,从 log 表中取出 ID 号,然后再从 A 表中取出相应的 ID 执行。


Python中如何编写SQL语句?
11 回复

select id from A where id in ( select id from log )


在Python里写SQL,一般用数据库驱动库(比如sqlite3、psycopg2、pymysql)或者ORM(比如SQLAlchemy、Django ORM)。直接写SQL的话,用参数化查询防止SQL注入,别用字符串拼接。

举个例子,用sqlite3查数据:

import sqlite3

# 连接到数据库(没有就创建)
conn = sqlite3.connect('example.db')
cursor = conn.cursor()

# 建表
cursor.execute('''CREATE TABLE IF NOT EXISTS users
                  (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')

# 插入数据,用?占位符
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 30))
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 25))

# 查询数据
cursor.execute("SELECT * FROM users WHERE age > ?", (26,))
rows = cursor.fetchall()
for row in rows:
    print(row)

# 提交并关闭
conn.commit()
conn.close()

用ORM(比如SQLAlchemy)更省事,把表结构定义成Python类,不用手写SQL:

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

# 创建引擎和会话
engine = create_engine('sqlite:///example.db')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

# 插入数据
user1 = User(name='Alice', age=30)
user2 = User(name='Bob', age=25)
session.add_all([user1, user2])
session.commit()

# 查询数据
users = session.query(User).filter(User.age > 26).all()
for user in users:
    print(user.id, user.name, user.age)

session.close()

简单说,新手建议先用sqlite3练手,项目大了用ORM更稳。

或者你可以 join

为什么这么麻烦要 log 表。
A 表多一个字段记录运行状态,如果运行有问题,标记一下这个字段。
等到全都运行完了后,取 A 表中运行状态字段是你标记的值的记录就行了。

select a.id from log l left join A a on l.A_id=a.id where l.id=xxxx

嗯,之前就是这么想的,后来要求保存错误原因,才单设一个 log 表



OK,搞定了,谢谢

不要用 IN,不要用 IN,不要用 IN…
尤其是带子查询的 IN,DEPENDENT SUBQUERY 的性能非常有问题
4 楼的 JOIN 更好一点…

bingo

你这是数据类的系统么?如果不是,还不如直接在代码层面做错误日志收集呢。如果是,为什么不对全局做操作日志呢?

感觉 3 楼说的有道理啊。

回到顶部