SQLAlchemy使用默认值批量插入缺少值

时间:2017-07-17 05:18:55

标签: python sqlalchemy sql-insert

问题陈述 -

我想使用SQLAlchemy批量插入几百行。架构如下所示

all_scrips_tbl = Table('all_scrips_info', _METADATA, Column('security_isin', String(16), primary_key=True), Column('company_name', String(80)), Column('nse_traded', Boolean, default=False), Column('nse_start_date', Date, default=datetime.date(year=2001, day=1, month=1)), Column('bse_traded', Boolean, default=False), Column('bse_start_date', Date, default=datetime.date(year=2001, day=1, month=1)), ) 现在每个脚本可以是 - nse_traded=Truebse_traded=True或两者nse_traded=True and bse_traded=True

所以我有插入语句,如 -

对于仅nse_traded=True的证券 ins = t.insert().values(security_isin=nstock.isin, company_name=nstock.name, nse_traded=True, nse_start_date=nstart_date, )

对于只有bse_traded=True -

的证券

ins = t.insert().values(security_isin=bstock.isin, company_name=bstock.name, bse_traded=True, bse_start_date=bstart_date)

并相应地针对nse_traded=Truebse_traded=True

我想批量插入这些陈述。所以像values().compile这样的东西与create语句中的默认值一样非常有用,这样我就可以使用以下内容了 -

conn.execute(all_scrips_info.insert() , [ {}, {} ] ) 在哪里使用默认值填充dicts?

我也看了this个问题,但这与我的要求略有不同。有一个old question on google groups,与我的要求相似。但sqlalchemy版本相当陈旧,加上答案不是很容易理解。

我错过了一些非常明显的东西吗?

1 个答案:

答案 0 :(得分:0)

下面我提供一个简单示例,说明如何使用SQLAlchemy更轻松地将CSV文件中的数据插入数据库。此处的默认值是创建的日期。在init函数中,您可以添加更多逻辑...在创建对象时应用此逻辑。

我想指出其他方法可用。请参阅SQLAlchemy文档:http://docs.sqlalchemy.org/en/latest/orm/persistence_techniques.html#bulk-operations

示例:

import csv
from io import StringIO
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from datetime import datetime

# Setting up model

Base = declarative_base()


class Car(Base):
    __tablename__ = 'car'

    id = Column('id', Integer, primary_key=True)
    created = Column('created', DateTime, default=datetime.now())
    brand = Column(String(250))
    nr_gears = Column('nr_gears', Integer)

    def __init__(self, brand, nr_gears):
        self.brand = brand
        self.nr_gears = nr_gears

        # You can place logic,conditions here when creating the objects. Now only use of default date - creation

    def __repr__(self):
        return '{created}\t{brand} (nr of gears: {nr_gears})'.format(
            created=datetime.strftime(self.created, '%d/%m/%Y'), brand=self.brand, nr_gears=self.nr_gears)


engine = create_engine('sqlite:///')
session = sessionmaker()
session.configure(bind=engine)
ex_ses = session()
Base.metadata.create_all(engine)

# Reading in some dummy data

csv_data = \
    '''Audi,5
    BMW,5
    Mercedes-Benz,5
    Opel,5
    Porsche,6
    Volkswagen,5
    Acura,5
    Datsun,6
    Honda,6
    Infiniti,5
    Isuzu,6
    Lexus,5
    Mazda,5
    Mitsubishi,5
    Nissan,5
    Suzuki,6
    Toyota,6
    Subaru,6'''

with StringIO(csv_data) as car_csv:
    cars_data = []
    readCSV = csv.reader(car_csv, delimiter=',')
    for row in readCSV:
        # Add data to the session.
        ex_ses.add(Car(brand=row[0], nr_gears=row[1]))

ex_ses.commit()

# Query
cars = (ex_ses.query(Car).all())
print('Created\t\tBrand (nr of gears)')
print('-' * 45)
for car in cars:
    print(car)

# output:
'''
Created     Brand (nr of gears)
---------------------------------------------
18/07/2017  Audi (nr of gears: 5)
18/07/2017  BMW (nr of gears: 5)
18/07/2017  Mercedes-Benz (nr of gears: 5)
18/07/2017  Opel (nr of gears: 5)
18/07/2017  Porsche (nr of gears: 6)
18/07/2017  Volkswagen (nr of gears: 5)
18/07/2017  Acura (nr of gears: 5)
18/07/2017  Datsun (nr of gears: 6)
18/07/2017  Honda (nr of gears: 6)
18/07/2017  Infiniti (nr of gears: 5)
18/07/2017  Isuzu (nr of gears: 6)
18/07/2017  Lexus (nr of gears: 5)
18/07/2017  Mazda (nr of gears: 5)
18/07/2017  Mitsubishi (nr of gears: 5)
18/07/2017  Nissan (nr of gears: 5)
18/07/2017  Suzuki (nr of gears: 6)
18/07/2017  Toyota (nr of gears: 6)
18/07/2017  Subaru (nr of gears: 6)
'''

希望这有帮助。

编辑根据我在下面扩展了Car类的评论。如果缺少齿轮数...则使用默认值9。这当然是一个有限的例子,但(我希望)显示了使用默认值的可能性......

class Car(Base):
    __tablename__ = 'car'

    id = Column('id', Integer, primary_key=True)
    created = Column('created', DateTime, default=datetime.now())
    brand = Column(String(250))
    nr_gears = Column('nr_gears', Integer,default=None)

    def __init__(self, brand, nr_gears):
        self.brand = brand

        if nr_gears is None or nr_gears == '':
            nr_gears = 9

        self.nr_gears = nr_gears

        # You can place logic,conditions here when creating the objects. Now only use of default date - creation

    def __repr__(self):
        return '{created}\t{brand} (nr of gears: {nr_gears})'.format(
            created=datetime.strftime(self.created, '%d/%m/%Y'), brand=self.brand, nr_gears=self.nr_gears)