SqlAlchemy один-ко-многим, только один к одному - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь создать таблицу, которая имеет много отношений «один ко многим» с 3 отдельными таблицами.Структура и код одинаковы для всех 3 таблиц, за исключением того, что в некоторых таблицах столбцов больше, чем в других.Для простоты я включил только одну из реляционных таблиц.

Каждое значение в столбце 'symbol_col' имеет отношение с каждым столбцом и вводит несколько значений в каждый столбец.Когда я запускал код до того, как вернулся, Traceback (последний последний вызов):

  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1170, in _execute_context
    context)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\sqlalchemy\dialects\mysql\mysqldb.py", line 105, in do_executemany
    rowcount = cursor.executemany(statement, parameters)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\cursors.py", line 197, in executemany
    self._get_db().encoding)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\cursors.py", line 234, in _do_execute_many
    rows += self.execute(sql + postfix)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\cursors.py", line 170, in execute
    result = self._query(query)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\cursors.py", line 328, in _query
    conn.query(q)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\connections.py", line 516, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\connections.py", line 727, in _read_query_result
    result.read()
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\connections.py", line 1066, in read
    first_packet = self.connection._read_packet()
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\connections.py", line 683, in _read_packet
    packet.check_error()
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "C:\Users\blewi\PycharmProjects\binance\venv\lib\site-packages\pymysql\err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.IntegrityError: (1062, "Duplicate entry '1' for key 'PRIMARY'")

Затем я использовал try/except exc.IntegrityError as e: db.session.rollback(), и это инициировало передачу в базу данных, но фиксировал только один набор.

Я попытался использовать некоторые из советов, которые я нашел в: ( Flask «один ко многим» | SQLAlchemy ), но это привело к созданию большего количества проблем, и, казалось, сделало его таким же запутанным, как и раньше.

Я новичок в sql и flask, поэтому я пытаюсь получить больше знаний об этом, но я также хотел бы, чтобы код работал.Ниже приведен код:

from flask_sqlalchemy import SQLAlchemy as sa
from flask import Flask as fl
from sqlalchemy import exc
import pymysql

pymysql.install_as_MySQLdb()

app = fl(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 
'mysql://root:the_other_stuff'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
DEBUG = True
db = sa(app)


class symbol(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    _symbol = db.Column('symbol_col', db.VARCHAR(45))

    _time = db.relationship('time', backref='Symbol', lazy=True)

    _open_close = db.relationship('open_close', backref='Symbol', lazy=True)

    def __init__(self, id, _symbol):
        self.id = id
        self._symbol = _symbol


class time(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    open_time = db.Column(db.VARCHAR(45))
    close_time = db.Column(db.VARCHAR(45))
    symbol_id = db.Column(db.Integer, db.ForeignKey('symbol.id'))

    def __int__(self, open_time, close_time):
        self.id = id
        self.open_time = open_time
        self.close_time = close_time

def _symbol():
    for i in range(len(tickers)):
        data = tickers[i]
        id = i + 1
        db.session.add(symbol(id, data))
    db.create_all()
    return db.session.commit(), print('inserted in symbol')


_symbol()


def t_loop(a=0):
    for i in range(len(klines[a])):
        with db.session.no_autoflush:
            try:
                _symbol = symbol.query.filter(symbol._symbol == 
tickers[a]).first()
                o_t = klines[a][i][0]
                c_t = klines[a][i][6]
                id = i + 1
                db.session.add(time(id=id, open_time=o_t, close_time=c_t, 
Symbol=_symbol))
                db.session.commit()
            except exc.IntegrityError as e:
                db.session.rollback()
    if a < len(klines) - 1:
        a = a + 1
        t_loop(a=a)
    return print('inserted time')


t_loop(a=0)

db.create_all()
db.session.commit()

Я изменил приведенный выше код, чтобы он больше походил на ссылку, которую я прикрепил.Теперь он вводит несколько символов для каждого символа и выглядит так, как будто это удалось?

    class symbol(db.Model):

        id = db.Column('symbol_id', db.Integer, primary_key=True)
        symbol_col = db.Column('symbol_col', db.VARCHAR(45))

        _time = db.relationship('time', backref='Symbol', lazy=True)


    def __init__(self, symbol_col):
        self.symbol_col = symbol_col

    def __repr__(self):
        return '<symbol %r>' % self.id


    class time(db.Model):
        id = db.Column('time_id', db.Integer, primary_key=True)
        open_time = db.Column(db.VARCHAR(45))
        close_time = db.Column(db.VARCHAR(45))
        symbol_id = db.Column(db.Integer, db.ForeignKey('symbol.symbol_id'))
        symbols = db.relationship('symbol')

        def __int__(self, open_time, close_time, symbols):
            self.open_time = open_time
            self.close_time = close_time
            self.symbols = symbols

        def __repr__(self):
            return '<time %r>' % self.id

def t_loop(a=0):
    for i in range(len(klines[a])):
        try:
            s = symbol(symbol_col=tickers[a])
            t = time(open_time=klines[a][i][0], close_time=klines[a][i][6])
            s._time.append(t)
            db.session.add(s)
            db.session.add(t)

        except exc.IntegrityError as e:
            db.session.rollback()
        if a < len(klines) - 1:
            a = a + 1
            t_loop(a=a)
        return print('inserted time')


    t_loop(a=0)
...