简体   繁体   English

Python3/SQLite3 | 如何从一个列表或元组列表创建多个表?

[英]Python3/SQLite3 | How to create multiple tables from a list or list of tuples?

I have a list of tuples like so:我有一个像这样的元组列表:

>>> all_names = c.execute("""select name from fb_friends""")
>>> for name in all_names:
...     print(name)
('Jody Ann Elizabeth Lill',)
('Georgia Gee Smith',)
...(282 more)...
('Josh Firth',)
('Danny Hallas',)

And I want to create a table for each individual person.我想为每个人创建一个表格。 First I need to replace all spaces with an underscore in order to be SQLite3 table names, so I do that like so:首先,我需要用下划线替换所有空格,以便成为 SQLite3 表名,所以我这样做:

>>> all_names = c.execute("""select name from fb_friends""")
>>> for name in all_names:
...     friends_name = name[0].replace(" ", "_")
...     print(friends_name)
Jody_Ann_Elizabeth_Lill
Georgia_Gee_Smith
...(282 more)...
Josh_Firth
Danny_Hallas

So if I understand correctly I now have a list, not a list of tuples..?所以如果我理解正确的话,我现在有一个列表,而不是元组列表..? Which should be simple to create all my tables from this list like so:从这个列表中创建我的所有表应该很简单,如下所示:

>>> all_names = c.execute("""select name from fb_friends""")
>>> for name in all_names:
...     friends_name = name[0].replace(" ", "_")
...     c.execute("""create table {0} (`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `work` TEXT NOT NULL, `education` TEXT, `current_city` TEXT, `phone_number` TEXT, `dob` TEXT, `gender` TEXT, `sexual_orientation` TEXT, `religion` TEXT, `relationship_status` TEXT, `about_me` TEXT )""".format(friends_name))

But all it does is create a table from the first name in the list, I would have thought the for loop would iterate over the list of names and create a table for each one, which is what I want, can people please advise me on a few things:但它所做的只是从列表中的第一个名称创建一个表,我原以为for循环会遍历名称列表并为每个名称创建一个表,这就是我想要的,人们能否请教我一些事情:

  1. Is using the .replace method the best way to get the underscores in the names?使用.replace方法是在名称中获取下划线的最佳方法吗? If no then what is?如果不是,那是什么?
  2. Why is the for loop not iterating over each name to create the tables?为什么for循环不遍历每个名​​称来创建表? And how do I make it do that?我如何让它做到这一点?
  3. Are my methods correct at all?我的方法完全正确吗? If not then what methods would do it better?如果不是,那么什么方法会做得更好?

While your immediate issue is resolved likely due to the raw cursor not retrieving all records from database whereas cursor.fetchall() or list(cursor) imports all rows to client side (Python), a slight memory footprint but may ensure rows import in script, I would be remiss to not encourage best practices in database design.虽然您的直接问题可能是由于原始游标未从数据库中检索所有记录而cursor.fetchall() ,而cursor.fetchall()list(cursor)所有行导入客户端 (Python),但可能会占用少量内存,但可以确保在脚本中导入行,我不鼓励数据库设计中的最佳实践。

As mentioned in comments, reconsider this approach and normalize your entire database model for one-to-many or many-to-many relationships between tables as relational databases are intended to do.正如评论中提到的,重新考虑这种方法并将整个数据库模型规范化为表之间的一对多或多对多关系,就像 关系数据库打算做的那样。 This way you avoid the overhead, maintenance, and querying challenges of 280+ identically structured tables.通过这种方式,您可以避免 280 多个结构相同的表的开销、维护和查询挑战。

From your explanation, you sound like you need a distinct friends table with one-to-many links with workplaces and posts table and any others, all connected to a friendid as foreign keys.根据您的解释,您听起来像是需要一个独特的friends表,其中包含与workplacesposts表以及任何其他人的一对多链接,所有这些都作为外键连接到一个friendid Ultimately, you would create tables only once and populate data with append queries:最终,您只需创建一次表并使用附加查询填充数据:

-- CREATE TABLES
CREATE TABLE friends (
     `friendid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
     `first_name` TEXT, last_name TEXT,
     `work` TEXT, `education` TEXT, 
     `current_city` TEXT, `phone_number` TEXT, 
     `dob` TEXT, `gender` TEXT, `sexual_orientation` TEXT, 
     `religion` TEXT, `relationship_status` TEXT, `about_me` TEXT);

CREATE TABLE workplaces (
     `workplaceid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
     `friendid` INTEGER,
     `workplace` TEXT NOT NULL, 
     `city` TEXT, `state` TEXT);

CREATE TABLE posts (
     `postid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
     `friendid` INTEGER,
     `text` TEXT NOT NULL,
     `postdate` TEXT, `postlocation` TEXT);

-- POPULATE TABLES (adjust to actual tables/fields)  
INSERT INTO friends (first_name, last_name)
SELECT SUBSTR(`name`, 1, INSTR(`name`, " ")) AS first_name,
       SUBSTR(`name`, INSTR(`name`, " ")+1) AS last_name,
FROM fb_friends;

INSERT INTO workplaces (friendid, work, city)
SELECT f.friendid, w.work, w.city 
FROM fb_work w INNER JOIN friends f ON w.name = f.first_name & ' ' & f.last_name;

INSERT INTO posts (friendid, `text`, postdate)
SELECT f.friendid, p.post_text, p.post_date 
FROM fb_posts p INNER JOIN friends f ON p.name = f.first_name & ' ' & f.last_name;

please try out this solution:请尝试这个解决方案:

staff = ['a', 'b', 'c']


for name in staff:
    c.execute("CREATE TABLE IF NOT EXISTS %s (name TEXT);" % (name))

So after continually playing around with various methods I managed to figure out how to do this.因此,在不断尝试各种方法之后,我设法弄清楚了如何做到这一点。 In order to get the the code to work all that had to be done was to convert it to a list, like so:为了使代码工作,所有必须做的就是将其转换为列表,如下所示:

>>> all_names = c.execute("""select name from fb_friends""")
>>> names = list(all_names) # I just added this line and changed the variable names below
>>> for name in names:
...     friends_name = name[0].replace(" ", "_")
...     c.execute("""create table {0} (`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `work` TEXT NOT NULL, `education` TEXT, `current_city` TEXT, `phone_number` TEXT, `dob` TEXT, `gender` TEXT, `sexual_orientation` TEXT, `religion` TEXT, `relationship_status` TEXT, `about_me` TEXT )""".format(name))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM