【问题标题】:Python3/SQLite3 | How to create multiple tables from a list or list of tuples?Python3/SQLite3 |如何从列表或元组列表创建多个表?
【发布时间】:2017-03-27 07:14:36
【问题描述】:

我有一个这样的元组列表:

>>> 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',)

我想为每个人创建一个表。首先,我需要用下划线替换所有空格,以便成为 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

所以如果我理解正确,我现在有一个列表,而不是一个元组列表..?从这个列表中创建我的所有表格应该很简单,如下所示:

>>> 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))

但它所做的只是从列表中的第一个名称创建一个表,我原以为for 循环会遍历名称列表并为每个名称创建一个表,这就是我想要的,可以请大家给我一些建议:

  1. 使用.replace 方法是获取名称中下划线的最佳方法吗?如果不是,那是什么?
  2. 为什么for 循环不遍历每个名​​称来创建表?我该如何做到这一点?
  3. 我的方法完全正确吗?如果不是,那么什么方法会做得更好?

【问题讨论】:

  • 在使用 for 循环遍历 'all_names' 变量之前是什么样子的?
  • 它是一个 sqlite3.Cursor 对象,所以我需要迭代以从中获取任何东西,不是吗?
  • >>> all_names = c.execute("""select name from fb_friends""") >>> print(all_names) <sqlite3.Cursor object at 0xb7211de0>
  • try: list(all_names) 我要求您在跳入循环之前显示您正在迭代的内容,因为循环似乎只迭代一次。换句话说,你确定 all_names 有很多条目要迭代吗?另一种测试方法是注释掉 c.execute() 调用,然后在 print 语句中添加名称。
  • 我想为每个人创建一个表...在数据库世界中,这是非常不明智的,因为它偏离了第三范式关系模型。另外,这可能是一个失控的脚本,因为 fb_friends 可能会迅速增长以阻碍数据库。为什么要构建 280 多个相同结构的表?只需使用一个带有 name 作为字段的人员表。查询将变得更加容易,并且可以有效地扩展。

标签: python list python-3.x sqlite tuples


【解决方案1】:

请试试这个解决方案:

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


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

【讨论】:

    【解决方案2】:

    虽然您的直接问题可能由于原始游标未从数据库中检索所有记录而得到解决,而 cursor.fetchall() or list(cursor) 将所有行导入客户端(Python),内存占用量很小,但可以确保行在脚本中导入,我会疏忽不鼓励数据库设计的最佳实践。

    如 cmets 中所述,重新考虑这种方法并将整个数据库模型标准化为表之间的一对多或多对多关系,就像 relational databases 打算做的那样。这样您就可以避免 280 多个结构相同的表所带来的开销、维护和查询挑战。

    根据您的解释,您听起来需要一个独特的friends 表,其中包含与workplacesposts 表以及任何其他表的一对多链接,所有这些都连接到friendid 作为外键。最终,您将只创建一次表并使用附加查询填充数据:

    -- 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;
    

    【讨论】:

    • 嘿,谢谢,我在这种方式的数据库(更大的数据集)方面并没有太多经验,并且在过去的 24 小时里一直在寻找和学习如何创建规范化数据库,昨晚我很难理解什么那些家伙在 cmets 上说,我不知道你的答案会怎么想,但是在花了一些时间学习之后,我现在了解了关系数据库的基本原理,我得到了一个小软件称为 WWW DATABASE DESIGNER,它对我有很大帮助,也是我脑海中浮现的一件事,这是由一位....说的。
    • Facebook MySQL 开发人员认为数据库设计是一种艺术形式。感谢您的建议,非常感谢 :)
    【解决方案3】:

    因此,在不断尝试各种方法之后,我设法弄清楚了如何做到这一点。为了使代码正常工作,只需将其转换为列表,如下所示:

    >>> 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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 2022-12-08
      • 1970-01-01
      • 2014-01-24
      • 2020-03-18
      • 1970-01-01
      相关资源
      最近更新 更多