Python中关于sqlalchemy表结构定义的两个问题请教

           class Person(Base):
            __tablename__ = "person"
            id = Column(Integer, primary_key=True, autoincrement=True)
            name = Column(String(10), nullable=False)
            age = Column(Integer, nullable=False)
        def __repr__(self):
            return "id:%s,name:%s,age:%s" %(self.id,self.name,self.age)

    person = Person(name="jack",age=20)
    session.add(person)
    session.commit()

1、这句:“ name = Column(String(10), nullable=False)”,官网对 Column 这个函数的说明(我 E 文理解不好),如果 Person 类不用来建表(其实表在库里面,以前就有的,目前操作要达到的目的只是 insert 或者 update ),似乎只用以下的方式就可以了,不用写 String 的长度,不写默认 null 是否允许也是可以的,理解对不对? 其实我也做了个测试,内容是可以写进表的(除了“ id = Column(Integer, primary_key=True, autoincrement=True"这句,必须声明"id"要自增长的参数,否则写入失败)

name = Column(String)

我想问的问题是,在 insert 或者 update 的时候,对于字段数据的类型,长度不说明,sqlalchemy 会怎么样的情况?注不注明比较好?如果 sqlalchemy 的表结构类里,写错了,又会怎么样呢(我自己动手的实验里,跟真实表不一致数据类型,也能写入)

2、第二个问题是承接第一种情况,(就一个)库里已经有过百张表(不要问为什么,我也懵逼),表的字段内容都几乎在 20 个 Column 以上,在使用 sqlalchemy 的时候,几乎要对一半以上的表做操作,那么在定义表结构类的时候,逐一明细写清楚?
这里有个问题,有什么便捷方法,把 mysqk 表结构轻松转成 sqlalchemy 的类定义表达呢?


Python中关于sqlalchemy表结构定义的两个问题请教

2 回复

问题1:如何定义表结构(模型类)?

用SQLAlchemy的声明式基类来定义,最常用的是declarative_base。下面是个完整例子:

from sqlalchemy import Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.orm import declarative_base, relationship
from datetime import datetime

# 创建基类
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True, nullable=False)
    email = Column(String(100), unique=True, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    
    # 定义一对多关系
    posts = relationship('Post', back_populates='author')
    
    def __repr__(self):
        return f"<User(id={self.id}, username='{self.username}')>"

class Post(Base):
    __tablename__ = 'posts'
    
    id = Column(Integer, primary_key=True)
    title = Column(String(200), nullable=False)
    content = Column(Text)
    user_id = Column(Integer, ForeignKey('users.id'))
    
    # 定义反向关系
    author = relationship('User', back_populates='posts')
    
    def __repr__(self):
        return f"<Post(id={self.id}, title='{self.title}')>"

关键点:

  • __tablename__ 必须设置,对应数据库表名
  • Column 定义字段,第一个参数是字段类型
  • primary_key=True 设置主键
  • nullable=False 表示非空约束
  • unique=True 设置唯一约束
  • ForeignKey 定义外键
  • relationship 定义ORM关系,不是数据库字段

问题2:如何创建/更新表结构?

创建所有表:

from sqlalchemy import create_engine

# 创建数据库连接
engine = create_engine('sqlite:///mydatabase.db')

# 创建所有表(如果不存在)
Base.metadata.create_all(engine)

更新表结构(使用Alembic迁移工具):

# 1. 初始化Alembic
alembic init alembic

# 2. 修改alembic.ini中的数据库连接
# sqlalchemy.url = driver://user:pass@localhost/dbname

# 3. 修改env.py导入Base
# from your_app.models import Base
# target_metadata = Base.metadata

# 4. 创建迁移脚本
alembic revision --autogenerate -m "添加新字段"

# 5. 执行迁移
alembic upgrade head

总结:用声明式基类定义模型,用Alembic管理迁移。


不写 model 的方式,使用 ORM 操作已存在的表,sqlalchemy 提供自动 map 功能 https://docs.sqlalchemy.org/en/13/orm/extensions/automap.html

从表结构生成 model 代码的方式: https://pypi.org/project/sqlacodegen/

回到顶部