[issue44927] [sqlite3] insert
New submission from AR : I propose to add an insert method to a SQLite cursor object, believe this could greatly improve readability of python code when you have to do a lot of insert operations to a different tables. Currently we have to create a dictionary with SQL's for each table: insert_sql = {'form_a': """INSERT INTO table_a (field_a1, field_a2) VALUES(:f1, :f2)""", 'form_b': """INSERT INTO table_b (field_b1, field_b2, field_b3) VALUES(:f1, :f2, :f3), other SQL statements }""" or we may use version with unnamed parameters: insert_sql = {'form_a': """INSERT INTO table_a (field_a1, field_a2) VALUES(?, ?)""", 'form_b': """INSERT INTO table_b (field_b1, field_b2, field_b3) VALUES(?, ?, ?), other SQL statements }""" The first one is conveniently compatible with cx_Oracle bind variable syntax, rows that are inserted are essentially dictionary. As dictionary is a mutable type, some extra freedom during construction of the row is allowed. The second syntax(qmark style) is specific to SQLite, rows that are inserted should have tuple type (namedtuple for us to be able to extract field names at later stage). entries_dict = [{'field_a1': 100, 'field_a2': 'sample1'}, {'field_a1': 500, 'field_a2': 'sample2'}] DataRow = namedtuple('DataRow', ['field_a1', 'field_a2']) entries_namedtuple = [DataRow(101, 'sample3'), DataRow(505, 'sample4')] In order to do an insert, you have to use either execute, or executemany: cursor.executemany(insert_sql['form_a'], entries_dict) or cursor.execute(insert_sql['form_a'], entries_dict[0]) Now let's move towards future insert method of cursor. As a first step, lets create SQL statement on the fly: table_name = 'table_a' #in case of a list of dictionaries: sql = """INSERT INTO {} ({}) VALUES({})""".format(table_name, ', '.join([str(key) for key in entries_dict[0]]), ', '.join([':' + str(key) for key in entries_dict[0]])) #currently, to do an insert operation, we have to: cursor.executemany(sql, entries_dict) #in case of a list of namedtuples: sql = """INSERT INTO {} ({}) VALUES({})""".format(table_name, ', '.join([str(field) for field in entries_namedtuple[0]._fields]), ', '.join(['?' for field in entries_namedtuple[0]._fields])) #currently, to do an insert operation, we have to: cursor.executemany(sql, entries_namedtuple) Now back to the proposal of insert method with unified syntax (one/many and dict/namedtuple). Let's do a second step and add an Insert method to a Cursor. The idea is to provide this method with table name, extract column names from supplied dict/namedtuple and use SQL generators from above. Than we could replace old cursor.executemany syntax with: cursor.insert(table_name, entries_dict) or cursor.insert(table_name, entries_dict[0]) or cursor.insert(table_name, entries_tuple) Since we may insert all, or any row of two types, this looks even more pythonic than pymongo(MongoDB) approach: collection.insert_many(entries_dict) Actually, the fact that pymongo insert code is so much cleaner and concise drew my attention. Other aspects of that lib are totally different story. I do not propose to generalize, or to move towards ORM or pymongo way of doing things. The scope is limited - lets do a convenient insert. Simplified implementation could be like this: def insert(self, table_name, entries): if(type(entries) == list): # several records(rows) need to be inserted do_insert = self.executemany if(hasattr(entries[0], '_fields')): #NamedTuple sql = "INSERT INTO {} ({}) VALUES({})".format(table_name, ', '.join([str(field) for field in entries[0]._fields]), ', '.join(['?' for field in entries[0]._fields])) elif(type(entries[0] == dict)): #dict sql = "INSERT INTO {} ({}) VALUES({})".format(table_name, ', '.join([str(key) for key in entries[0]]), ', '.join([':' + str(key) for key in entries[0]])) else: #just one record(row) do_insert = self.execute if(hasattr(entries, '_fields')):#NamedTuple sql = "INSERT INTO {} ({}) VALUES({})".format(table_name, ', '.join([str(field) for fiel
[issue44927] [sqlite3] proposal: add sqlite3.Cursor.insert() method
AR added the comment: There is no good solution to this. Either a move to all-in-one solution and ORM at the end, or limited scope hack that allow for a convenient "just insert". I do not insist due to this controversy I just didn't realize the difference until I've noticed that one line of my pymongo code corresponds to many lines of sqlite code. I'm perfectly fine using direct SQL statements, but would happily use a shortcut. It's up to you to decide as you see a broader picture. Thank you in any case! -- ___ Python tracker <https://bugs.python.org/issue44927> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42730] TypeError/hang inside of Time.Sleep() when _thread.interrupt_main()
AR Kareem added the comment: My apologies, I meant to flag it as 3.6 instead of 3.7. I see what's happening now, and thanks for providing the correct way to raise a KeyboardInterrupt. Correctly flagged as 3.6 and closed. Thanks. -- resolution: -> duplicate versions: +Python 3.6 -Python 3.7 ___ Python tracker <https://bugs.python.org/issue42730> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue42730] TypeError/hang inside of Time.Sleep() when _thread.interrupt_main()
AR Kareem added the comment: Shouldn't the behaviour for _thread.interrupt_main() be always to interrupt the main thread. I would expect that if a child thread uses _thread.interrupt_main() that the main thread be interrupted regardless of how the python script was invoked. Wouldn't it be more reasonable to make _thread.interrupt_main() always raise a SIGINT? I'm not sure if this is technically considered a bug or not, but it seems that it's not functioning as intended even in Python 3.7 -- ___ Python tracker <https://bugs.python.org/issue42730> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue39905] Cannot load sub package having a 3-dot relative import
New submission from Yon Ar Chall : Hi there ! I was trying to use importlib.util.spec_from_file_location() to import a nested package containing a 3-dot relative import. $ tree ~/myproj /home/yon/myproj └── mypkg ├── __init__.py └── subpkg ├── __init__.py ├── subsubpkg_abs │ └── __init__.py └── subsubpkg_rel └── __init__.py Relative import here : $ cat ~/myproj/mypkg/subpkg/subsubpkg_rel/__init__.py from ... import subpkg Absolute import here (for comparison purpose) : $ cat ~/myproj/mypkg/subpkg/subsubpkg_abs/__init__.py import mypkg.subpkg $ python3 Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from importlib.util import spec_from_file_location >>> spec = spec_from_file_location("subsubpkg_abs", >>> "/home/yon/myproj/mypkg/subpkg/subsubpkg_abs/__init__.py") >>> spec.loader.load_module() >>> spec = spec_from_file_location("subsubpkg_rel", >>> "/home/yon/myproj/mypkg/subpkg/subsubpkg_rel/__init__.py") >>> spec.loader.load_module() Traceback (most recent call last): File "", line 1, in File "", line 388, in _check_name_wrapper File "", line 809, in load_module File "", line 668, in load_module File "", line 268, in _load_module_shim File "", line 693, in _load File "", line 673, in _load_unlocked File "", line 665, in exec_module File "", line 222, in _call_with_frames_removed File "/home/yon/myproj/mypkg/subpkg/subsubpkg_rel/__init__.py", line 1, in from ... import subpkg ValueError: attempted relative import beyond top-level package >>> Raw import just works (as importlib.import_module() does) : >>> import mypkg.subpkg.subsubpkg_rel >>> -- components: Library (Lib) messages: 363678 nosy: yon priority: normal severity: normal status: open title: Cannot load sub package having a 3-dot relative import versions: Python 3.5 ___ Python tracker <https://bugs.python.org/issue39905> ___ ___ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com