0

Good day. Please help me with a problem.

I'm having trouble updating / reading data in a thread when using ORM.

I've been using peewee for Python. After reading the documentation starting to initialize the object to work with the database.

db = SqliteDatabase('db.sqlite', threadlocals=True)

# Next comes the creation of tables and filling.
class Products(Model):
    id = IntegerField(index=True, primary_key=True)
    count_sales = IntegerField()
    updated = IntegerField() # default to zero

    class Meta:
        database = db

db.connect()
db.create_tables([Products, ...]) # I have several tables

# I continue to fill the table with data from a file

I then create a predetermined amount of threads as follows:

class MyThread(Thread):
    tables = None
    db = None

    def run(self):
        products_update(self.tables, self.db)

for _ in range(1, 20):
    t = MyThread()
    t.tables = (Products, ...)
    t.db = db
    t.start()

The function counts the number of records in the field count sales, and there they are, it changes randomly one of them.

def products_update(tables, db):
    Products, ... = tables

    count = Products.select().where(Products.count_sales < 10, Products.updated == 0).limit(1).count()
    if count:
        row = Products.select().where(Products.count_sales < 10, Products.updated == 0).order_by(random()).limit(1).get()

        Products.update(updated=1).where(Products.id == row.id).execute()

I need to make the process of finding and updating was linear.

Thank you for your attention. I apologize for the language I used a translator.

  • Could you please give examples: what goes wrong with your current approach, and what would be a correct result? – 9000 Jan 07 '15 at 19:17
  • @9000 https://gist.github.com/ismkv/b1d7021af623e886f7ec here an example, at the end of the result of. As can be seen from the second thread should find no records of 40 and 39, 38, 37. (Может на русском будет легче общаться?) – mysuperlogin Jan 07 '15 at 19:54
  • На русском нормально, елси что, но тут не принято. Everyone is expected to be able to read the questions and comments, hence English. – 9000 Jan 07 '15 at 20:02
  • Хорошо, тогда будем переводить ответ. Думаю, на русском у меня лучше выйдет выразить свои мысли. (Well, then we will translate the answer. I think in Russian I will better express their thoughts.) Что скажите насчет моей проблемы? (What do you say about my problems?) – mysuperlogin Jan 07 '15 at 20:04
  • 1
    I'd say that with threads but without locks you cannot expect any order of execution. It looks like every thread yields on update, so you have 4-5 threads running a `select` before any of them runs an `update`. Or maybe it's the autocommit behavior (you don't issue an explicit `commit` anywhere), so the actual updates are visible only after a thread dies and closes the connection. (Перевести?) – 9000 Jan 07 '15 at 20:10
  • Да. И, если не затруднит, с примером. – mysuperlogin Jan 07 '15 at 20:18
  • I have commented [the gist](https://gist.github.com/ismkv/b1d7021af623e886f7ec). – 9000 Jan 07 '15 at 20:43
  • You need to control thread access to the shared database. A simple way to do this is with a `threading.Lock`. A trivial example for printing to stdout is shown in [this answer](http://stackoverflow.com/a/18283388/355230) of mine. – martineau Jan 07 '15 at 20:55
  • @9000, Also there to answer. **martineau**, Thanks for the reply, I will now look at. – mysuperlogin Jan 07 '15 at 21:07
  • You're welcome -- assuming you meant "this is what **I** need" ;-). In concurrent programming, access to all shared resource has to be controlled, locks are but one way. – martineau Jan 07 '15 at 21:41
  • @martineau That's just one problem in my code function call "time.sleep" and it "slows down" the trade, it can be bypassed? – mysuperlogin Jan 07 '15 at 21:45
  • Yes, the topic of parallel programming is very interesting (especially now). – mysuperlogin Jan 07 '15 at 21:46
  • If you were trying to use `time.sleep()` to control access then you can remove it or them if you are now doing it another way (as suggested). I am not familiar with `peewee`. – martineau Jan 07 '15 at 21:49
  • No. The code is a reference to a remote server and you need to wait a couple of seconds to get a response from him. – mysuperlogin Jan 07 '15 at 21:52
  • 1
    If you're having to wait due to slow server response, using multi-threading may be pointless. – martineau Jan 07 '15 at 21:56
  • Just the same option, which I described in the question copes well with this task, but there are difficulties with reading from the database. In your example, the problem with waiting :) So I need to dig in the direction of the correct use of the database in the trade. – mysuperlogin Jan 07 '15 at 22:05

0 Answers0