Python使用SQLAlchemy ORM在MySQL中创建外键的正确实现方式咨询
外键正确实现方案
你当前使用的是SQLAlchemy Core的原生表构造语法,本身是合法的写法,和ORM模型类的外键逻辑一致,只需要修正以下两个问题即可完成外键配置:
核心修正:给外键列添加明确列名
你现在的外键定义没有指定字段名,这是运行报错的核心原因。只需要给关联strategies.id的外键列指定列名(推荐命名为strategy_id)即可,修改示例如下:
# renko_bars表外键修改 Column('strategy_id', CHAR(32), ForeignKey('strategies.id'), nullable=False), # trades表外键修改 Column('strategy_id', CHAR(32), ForeignKey('strategies.id'), nullable=False),
可选优化:统一MetaData实例
你当前每个建表方法都单独实例化了MetaData()对象,只要你保持现在先建strategies表、再建另外两个子表的执行顺序,单独的MetaData实例也能正常运行。但统一使用同一个MetaData实例更规范,能避免后续表关联出现元数据不一致的问题,修改后的完整代码如下:
import sqlalchemy from sqlalchemy import MetaData, Table, Column, CHAR, DATETIME, TEXT, DOUBLE, INTEGER, ForeignKey, BIGINT class Database: # 统一配置数据库连接参数 USER = "你的用户名" PASSWORD = "你的密码" HOST = "你的地址" DB_NAME = "你的库名" def __init__(self): self.engine = sqlalchemy.create_engine( 'mysql+mysqldb://{}:{}@{}/{}'.format(self.USER, self.PASSWORD, self.HOST, self.DB_NAME)) # 全局统一MetaData实例 self.meta = MetaData() # 建表顺序必须保证依赖表先创建:strategies先建,子表后建 self.create_strategies_table() self.create_renko_bars_table() self.create_trades_table() # 统一执行建表(也可以保留原来单表create_all的写法) self.meta.create_all(self.engine, checkfirst=True) def create_strategies_table(self): self.strategies = Table( 'strategies', self.meta, # PRIMARY KEY Column('id', CHAR(32), primary_key=True, nullable=False), Column('start_time', DATETIME, nullable=False), Column('symbol', TEXT(), nullable=False), Column('brick_size', DOUBLE(), nullable=False), Column('method', TEXT(), nullable=False), Column('entry_points', TEXT(), nullable=True), Column('exit_points', TEXT(), nullable=True), Column('take_profit', INTEGER(), nullable=True), Column('stop_loss', INTEGER(), nullable=True), Column('balance', DOUBLE(), nullable=True), Column('trades', INTEGER(), nullable=True), ) def create_renko_bars_table(self): self.renko_bars = Table( 'renko_bars', self.meta, # 修正后的外键列 Column('strategy_id', CHAR(32), ForeignKey('strategies.id'), nullable=False), Column('price_last', DOUBLE(), nullable=False), Column('price_renko', DOUBLE(), nullable=False), Column('price_min', DOUBLE(), nullable=False), Column('price_max', DOUBLE(), nullable=False), Column('dt_start', DATETIME(), nullable=False), Column('dt_end', DATETIME(), nullable=False), Column('trend', INTEGER(), nullable=False), Column('volume', BIGINT(), nullable=False), Column('count', INTEGER(), nullable=False), Column('cons_up', INTEGER(), nullable=False), Column('cons_down', INTEGER(), nullable=False), ) def create_trades_table(self): self.trades = Table( 'trades', self.meta, # 修正后的外键列 Column('strategy_id', CHAR(32), ForeignKey('strategies.id'), nullable=False), Column('symbol', TEXT(), nullable=False), Column('side', INTEGER(), nullable=False), Column('size', BIGINT(), nullable=False), Column('entry_time', DATETIME(), nullable=False), Column('exit_time', DATETIME(), nullable=False), Column('entry_price', DOUBLE(), nullable=False), Column('exit_price', DOUBLE(), nullable=False), Column('entry_reason', TEXT(), nullable=True), Column('exit_reason', TEXT(), nullable=True), Column('pal', DOUBLE(), nullable=False), Column('net_pal', DOUBLE(), nullable=False), Column('commissions', DOUBLE(), nullable=False), )
验证方式
建表完成后,可直接在MySQL中执行命令查看外键约束是否生效:
SHOW CREATE TABLE renko_bars;
返回结果中能看到FOREIGN KEY (strategy_id) REFERENCES strategies(id)的约束声明即为配置成功。
内容的提问来源于stack exchange,提问作者orie
相关产品推荐
相关产品推荐

