Guest User

Untitled

a guest
Oct 19th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.71 KB | None | 0 0
  1. sebastien@hermes4:~/DEV/openerp/v61/openobject-server$ bzr diff
  2. === modified file 'openerp/osv/orm.py'
  3. --- openerp/osv/orm.py 2011-07-05 12:22:22 +0000
  4. +++ openerp/osv/orm.py 2011-07-06 23:35:02 +0000
  5. @@ -2714,6 +2714,233 @@
  6. cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, column['attname']))
  7. self.__schema.debug("Table '%s': column '%s': dropped NOT NULL constraint",
  8. self._table, column['attname'])
  9. +
  10. + def update_field(self, cr, create, column_data, k, f, context=None):
  11. + todo_end=False
  12. + if isinstance(f, fields.one2many):
  13. + self._o2m_raise_on_missing_reference(cr, f)
  14. +
  15. + elif isinstance(f, fields.many2many):
  16. + self._m2m_raise_or_create_relation(cr, f)
  17. +
  18. + else:
  19. + res = column_data.get(k)
  20. +
  21. + # The field is not found as-is in database, try if it
  22. + # exists with an old name.
  23. + if not res and hasattr(f, 'oldname'):
  24. + res = column_data.get(f.oldname)
  25. + if res:
  26. + cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % (self._table, f.oldname, k))
  27. + res['attname'] = k
  28. + column_data[k] = res
  29. + self.__schema.debug("Table '%s': renamed column '%s' to '%s'",
  30. + self._table, f.oldname, k)
  31. +
  32. + # The field already exists in database. Possibly
  33. + # change its type, rename it, drop it or change its
  34. + # constraints.
  35. + if res:
  36. + f_pg_type = res['typname']
  37. + f_pg_size = res['size']
  38. + f_pg_notnull = res['attnotnull']
  39. + if isinstance(f, fields.function) and not f.store and\
  40. + not getattr(f, 'nodrop', False):
  41. + self.__logger.info('column %s (%s) in table %s removed: converted to a function !\n',
  42. + k, f.string, self._table)
  43. + cr.execute('ALTER TABLE "%s" DROP COLUMN "%s" CASCADE' % (self._table, k))
  44. + cr.commit()
  45. + self.__schema.debug("Table '%s': dropped column '%s' with cascade",
  46. + self._table, k)
  47. + f_obj_type = None
  48. + else:
  49. + f_obj_type = get_pg_type(f) and get_pg_type(f)[0]
  50. +
  51. + if f_obj_type:
  52. + ok = False
  53. + casts = [
  54. + ('text', 'char', 'VARCHAR(%d)' % (f.size or 0,), '::VARCHAR(%d)'%(f.size or 0,)),
  55. + ('varchar', 'text', 'TEXT', ''),
  56. + ('int4', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
  57. + ('date', 'datetime', 'TIMESTAMP', '::TIMESTAMP'),
  58. + ('timestamp', 'date', 'date', '::date'),
  59. + ('numeric', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
  60. + ('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
  61. + ]
  62. + if f_pg_type == 'varchar' and f._type == 'char' and f_pg_size < f.size:
  63. + cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
  64. + cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" VARCHAR(%d)' % (self._table, k, f.size))
  65. + cr.execute('UPDATE "%s" SET "%s"=temp_change_size::VARCHAR(%d)' % (self._table, k, f.size))
  66. + cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
  67. + cr.commit()
  68. + self.__schema.debug("Table '%s': column '%s' (type varchar) changed size from %s to %s",
  69. + self._table, k, f_pg_size, f.size)
  70. + for c in casts:
  71. + if (f_pg_type==c[0]) and (f._type==c[1]):
  72. + if f_pg_type != f_obj_type:
  73. + ok = True
  74. + cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
  75. + cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, c[2]))
  76. + cr.execute(('UPDATE "%s" SET "%s"=temp_change_size'+c[3]) % (self._table, k))
  77. + cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
  78. + cr.commit()
  79. + self.__schema.debug("Table '%s': column '%s' changed type from %s to %s",
  80. + self._table, k, c[0], c[1])
  81. + break
  82. +
  83. + if f_pg_type != f_obj_type:
  84. + if not ok:
  85. + i = 0
  86. + while True:
  87. + newname = k + '_moved' + str(i)
  88. + cr.execute("SELECT count(1) FROM pg_class c,pg_attribute a " \
  89. + "WHERE c.relname=%s " \
  90. + "AND a.attname=%s " \
  91. + "AND c.oid=a.attrelid ", (self._table, newname))
  92. + if not cr.fetchone()[0]:
  93. + break
  94. + i += 1
  95. + if f_pg_notnull:
  96. + cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k))
  97. + cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (self._table, k, newname))
  98. + cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
  99. + cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''")))
  100. + self.__schema.debug("Table '%s': column '%s' has changed type (DB=%s, def=%s), data moved to column %s !",
  101. + self._table, k, f_pg_type, f._type, newname)
  102. +
  103. + # if the field is required and hasn't got a NOT NULL constraint
  104. + if f.required and f_pg_notnull == 0:
  105. + # set the field to the default value if any
  106. + if k in self._defaults:
  107. + if callable(self._defaults[k]):
  108. + default = self._defaults[k](self, cr, ROOT_USER_ID, context)
  109. + else:
  110. + default = self._defaults[k]
  111. +
  112. + if (default is not None):
  113. + ss = self._columns[k]._symbol_set
  114. + query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (self._table, k, ss[0], k)
  115. + cr.execute(query, (ss[1](default),))
  116. + # add the NOT NULL constraint
  117. + cr.commit()
  118. + try:
  119. + cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % (self._table, k), log_exceptions=False)
  120. + cr.commit()
  121. + self.__schema.debug("Table '%s': column '%s': added NOT NULL constraint",
  122. + self._table, k)
  123. + except Exception:
  124. + msg = "Table '%s': unable to set a NOT NULL constraint on column '%s' !\n"\
  125. + "If you want to have it, you should update the records and execute manually:\n"\
  126. + "ALTER TABLE %s ALTER COLUMN %s SET NOT NULL"
  127. + self.__schema.warn(msg, self._table, k, self._table, k)
  128. + cr.commit()
  129. + elif not f.required and f_pg_notnull == 1:
  130. + cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k))
  131. + cr.commit()
  132. + self.__schema.debug("Table '%s': column '%s': dropped NOT NULL constraint",
  133. + self._table, k)
  134. + # Verify index
  135. + indexname = '%s_%s_index' % (self._table, k)
  136. + cr.execute("SELECT indexname FROM pg_indexes WHERE indexname = %s and tablename = %s", (indexname, self._table))
  137. + res2 = cr.dictfetchall()
  138. + if not res2 and f.select:
  139. + cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (self._table, k, self._table, k))
  140. + cr.commit()
  141. + if f._type == 'text':
  142. + # FIXME: for fields.text columns we should try creating GIN indexes instead (seems most suitable for an ERP context)
  143. + msg = "Table '%s': Adding (b-tree) index for text column '%s'."\
  144. + "This is probably useless (does not work for fulltext search) and prevents INSERTs of long texts"\
  145. + " because there is a length limit for indexable btree values!\n"\
  146. + "Use a search view instead if you simply want to make the field searchable."
  147. + self.__schema.warn(msg, self._table, k, f._type)
  148. + if res2 and not f.select:
  149. + cr.execute('DROP INDEX "%s_%s_index"' % (self._table, k))
  150. + cr.commit()
  151. + msg = "Table '%s': dropping index for column '%s' of type '%s' as it is not required anymore"
  152. + self.__schema.debug(msg, self._table, k, f._type)
  153. +
  154. + if isinstance(f, fields.many2one):
  155. + ref = self.pool.get(f._obj)._table
  156. + if ref != 'ir_actions':
  157. + cr.execute('SELECT confdeltype, conname FROM pg_constraint as con, pg_class as cl1, pg_class as cl2, '
  158. + 'pg_attribute as att1, pg_attribute as att2 '
  159. + 'WHERE con.conrelid = cl1.oid '
  160. + 'AND cl1.relname = %s '
  161. + 'AND con.confrelid = cl2.oid '
  162. + 'AND cl2.relname = %s '
  163. + 'AND array_lower(con.conkey, 1) = 1 '
  164. + 'AND con.conkey[1] = att1.attnum '
  165. + 'AND att1.attrelid = cl1.oid '
  166. + 'AND att1.attname = %s '
  167. + 'AND array_lower(con.confkey, 1) = 1 '
  168. + 'AND con.confkey[1] = att2.attnum '
  169. + 'AND att2.attrelid = cl2.oid '
  170. + 'AND att2.attname = %s '
  171. + "AND con.contype = 'f'", (self._table, ref, k, 'id'))
  172. + res2 = cr.dictfetchall()
  173. + if res2:
  174. + if res2[0]['confdeltype'] != POSTGRES_CONFDELTYPES.get(f.ondelete.upper(), 'a'):
  175. + cr.execute('ALTER TABLE "' + self._table + '" DROP CONSTRAINT "' + res2[0]['conname'] + '"')
  176. + self._foreign_keys.append((self._table, k, ref, f.ondelete))
  177. + cr.commit()
  178. + self.__schema.debug("Table '%s': column '%s': XXX",
  179. + self._table, k)
  180. +
  181. + # The field doesn't exist in database. Create it if necessary.
  182. + else:
  183. + if not isinstance(f, fields.function) or f.store:
  184. + # add the missing field
  185. + cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
  186. + cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''")))
  187. + self.__schema.debug("Table '%s': added column '%s' with definition=%s",
  188. + self._table, k, get_pg_type(f)[1])
  189. +
  190. + # initialize it
  191. + if not create and k in self._defaults:
  192. + if callable(self._defaults[k]):
  193. + default = self._defaults[k](self, cr, ROOT_USER_ID, context)
  194. + else:
  195. + default = self._defaults[k]
  196. +
  197. + ss = self._columns[k]._symbol_set
  198. + query = 'UPDATE "%s" SET "%s"=%s' % (self._table, k, ss[0])
  199. + cr.execute(query, (ss[1](default),))
  200. + cr.commit()
  201. + netsvc.Logger().notifyChannel('data', netsvc.LOG_DEBUG, "Table '%s': setting default value of new column %s" % (self._table, k))
  202. +
  203. + # remember the functions to call for the stored fields
  204. + if isinstance(f, fields.function):
  205. + order = 10
  206. + if f.store is not True: # i.e. if f.store is a dict
  207. + order = f.store[f.store.keys()[0]][2]
  208. + todo_end = (order, self._update_store, (f, k))
  209. +
  210. + # and add constraints if needed
  211. + if isinstance(f, fields.many2one):
  212. + if not self.pool.get(f._obj):
  213. + raise except_orm('Programming Error', ('There is no reference available for %s') % (f._obj,))
  214. + ref = self.pool.get(f._obj)._table
  215. + # ir_actions is inherited so foreign key doesn't work on it
  216. + if ref != 'ir_actions':
  217. + self._foreign_keys.append((self._table, k, ref, f.ondelete))
  218. + self.__schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s",
  219. + self._table, k, ref, f.ondelete)
  220. + if f.select:
  221. + cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (self._table, k, self._table, k))
  222. + if f.required:
  223. + try:
  224. + cr.commit()
  225. + cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % (self._table, k), log_exceptions=False)
  226. + self.__schema.debug("Table '%s': column '%s': added a NOT NULL constraint",
  227. + self._table, k)
  228. + except Exception:
  229. + msg = "WARNING: unable to set column %s of table %s not null !\n"\
  230. + "Try to re-run: openerp-server --update=module\n"\
  231. + "If it doesn't work, update records and execute manually:\n"\
  232. + "ALTER TABLE %s ALTER COLUMN %s SET NOT NULL"
  233. + self.__logger.warn(msg, k, self._table, self._table, k)
  234. + cr.commit()
  235. + return todo_end
  236.  
  237. def _auto_init(self, cr, context=None):
  238. """
  239. @@ -2739,7 +2966,6 @@
  240. context = {}
  241. store_compute = False
  242. todo_end = []
  243. - update_custom_fields = context.get('update_custom_fields', False)
  244. self._field_create(cr, context=context)
  245. create = not self._table_exist(cr)
  246.  
  247. @@ -2766,234 +2992,13 @@
  248. for k, f in self._columns.iteritems():
  249. if k in ('id', 'write_uid', 'write_date', 'create_uid', 'create_date'):
  250. continue
  251. - # Don't update custom (also called manual) fields
  252. + # Don't update custom (also called manual) fields
  253. if f.manual and not update_custom_fields:
  254. continue
  255. -
  256. - if isinstance(f, fields.one2many):
  257. - self._o2m_raise_on_missing_reference(cr, f)
  258. -
  259. - elif isinstance(f, fields.many2many):
  260. - self._m2m_raise_or_create_relation(cr, f)
  261. -
  262. - else:
  263. - res = column_data.get(k)
  264. -
  265. - # The field is not found as-is in database, try if it
  266. - # exists with an old name.
  267. - if not res and hasattr(f, 'oldname'):
  268. - res = column_data.get(f.oldname)
  269. - if res:
  270. - cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % (self._table, f.oldname, k))
  271. - res['attname'] = k
  272. - column_data[k] = res
  273. - self.__schema.debug("Table '%s': renamed column '%s' to '%s'",
  274. - self._table, f.oldname, k)
  275. -
  276. - # The field already exists in database. Possibly
  277. - # change its type, rename it, drop it or change its
  278. - # constraints.
  279. - if res:
  280. - f_pg_type = res['typname']
  281. - f_pg_size = res['size']
  282. - f_pg_notnull = res['attnotnull']
  283. - if isinstance(f, fields.function) and not f.store and\
  284. - not getattr(f, 'nodrop', False):
  285. - self.__logger.info('column %s (%s) in table %s removed: converted to a function !\n',
  286. - k, f.string, self._table)
  287. - cr.execute('ALTER TABLE "%s" DROP COLUMN "%s" CASCADE' % (self._table, k))
  288. - cr.commit()
  289. - self.__schema.debug("Table '%s': dropped column '%s' with cascade",
  290. - self._table, k)
  291. - f_obj_type = None
  292. - else:
  293. - f_obj_type = get_pg_type(f) and get_pg_type(f)[0]
  294. -
  295. - if f_obj_type:
  296. - ok = False
  297. - casts = [
  298. - ('text', 'char', 'VARCHAR(%d)' % (f.size or 0,), '::VARCHAR(%d)'%(f.size or 0,)),
  299. - ('varchar', 'text', 'TEXT', ''),
  300. - ('int4', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
  301. - ('date', 'datetime', 'TIMESTAMP', '::TIMESTAMP'),
  302. - ('timestamp', 'date', 'date', '::date'),
  303. - ('numeric', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
  304. - ('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
  305. - ]
  306. - if f_pg_type == 'varchar' and f._type == 'char' and f_pg_size < f.size:
  307. - cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
  308. - cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" VARCHAR(%d)' % (self._table, k, f.size))
  309. - cr.execute('UPDATE "%s" SET "%s"=temp_change_size::VARCHAR(%d)' % (self._table, k, f.size))
  310. - cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
  311. - cr.commit()
  312. - self.__schema.debug("Table '%s': column '%s' (type varchar) changed size from %s to %s",
  313. - self._table, k, f_pg_size, f.size)
  314. - for c in casts:
  315. - if (f_pg_type==c[0]) and (f._type==c[1]):
  316. - if f_pg_type != f_obj_type:
  317. - ok = True
  318. - cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
  319. - cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, c[2]))
  320. - cr.execute(('UPDATE "%s" SET "%s"=temp_change_size'+c[3]) % (self._table, k))
  321. - cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
  322. - cr.commit()
  323. - self.__schema.debug("Table '%s': column '%s' changed type from %s to %s",
  324. - self._table, k, c[0], c[1])
  325. - break
  326. -
  327. - if f_pg_type != f_obj_type:
  328. - if not ok:
  329. - i = 0
  330. - while True:
  331. - newname = k + '_moved' + str(i)
  332. - cr.execute("SELECT count(1) FROM pg_class c,pg_attribute a " \
  333. - "WHERE c.relname=%s " \
  334. - "AND a.attname=%s " \
  335. - "AND c.oid=a.attrelid ", (self._table, newname))
  336. - if not cr.fetchone()[0]:
  337. - break
  338. - i += 1
  339. - if f_pg_notnull:
  340. - cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k))
  341. - cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (self._table, k, newname))
  342. - cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
  343. - cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''")))
  344. - self.__schema.debug("Table '%s': column '%s' has changed type (DB=%s, def=%s), data moved to column %s !",
  345. - self._table, k, f_pg_type, f._type, newname)
  346. -
  347. - # if the field is required and hasn't got a NOT NULL constraint
  348. - if f.required and f_pg_notnull == 0:
  349. - # set the field to the default value if any
  350. - if k in self._defaults:
  351. - if callable(self._defaults[k]):
  352. - default = self._defaults[k](self, cr, ROOT_USER_ID, context)
  353. - else:
  354. - default = self._defaults[k]
  355. -
  356. - if (default is not None):
  357. - ss = self._columns[k]._symbol_set
  358. - query = 'UPDATE "%s" SET "%s"=%s WHERE "%s" is NULL' % (self._table, k, ss[0], k)
  359. - cr.execute(query, (ss[1](default),))
  360. - # add the NOT NULL constraint
  361. - cr.commit()
  362. - try:
  363. - cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % (self._table, k), log_exceptions=False)
  364. - cr.commit()
  365. - self.__schema.debug("Table '%s': column '%s': added NOT NULL constraint",
  366. - self._table, k)
  367. - except Exception:
  368. - msg = "Table '%s': unable to set a NOT NULL constraint on column '%s' !\n"\
  369. - "If you want to have it, you should update the records and execute manually:\n"\
  370. - "ALTER TABLE %s ALTER COLUMN %s SET NOT NULL"
  371. - self.__schema.warn(msg, self._table, k, self._table, k)
  372. - cr.commit()
  373. - elif not f.required and f_pg_notnull == 1:
  374. - cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k))
  375. - cr.commit()
  376. - self.__schema.debug("Table '%s': column '%s': dropped NOT NULL constraint",
  377. - self._table, k)
  378. - # Verify index
  379. - indexname = '%s_%s_index' % (self._table, k)
  380. - cr.execute("SELECT indexname FROM pg_indexes WHERE indexname = %s and tablename = %s", (indexname, self._table))
  381. - res2 = cr.dictfetchall()
  382. - if not res2 and f.select:
  383. - cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (self._table, k, self._table, k))
  384. - cr.commit()
  385. - if f._type == 'text':
  386. - # FIXME: for fields.text columns we should try creating GIN indexes instead (seems most suitable for an ERP context)
  387. - msg = "Table '%s': Adding (b-tree) index for text column '%s'."\
  388. - "This is probably useless (does not work for fulltext search) and prevents INSERTs of long texts"\
  389. - " because there is a length limit for indexable btree values!\n"\
  390. - "Use a search view instead if you simply want to make the field searchable."
  391. - self.__schema.warn(msg, self._table, k, f._type)
  392. - if res2 and not f.select:
  393. - cr.execute('DROP INDEX "%s_%s_index"' % (self._table, k))
  394. - cr.commit()
  395. - msg = "Table '%s': dropping index for column '%s' of type '%s' as it is not required anymore"
  396. - self.__schema.debug(msg, self._table, k, f._type)
  397. -
  398. - if isinstance(f, fields.many2one):
  399. - ref = self.pool.get(f._obj)._table
  400. - if ref != 'ir_actions':
  401. - cr.execute('SELECT confdeltype, conname FROM pg_constraint as con, pg_class as cl1, pg_class as cl2, '
  402. - 'pg_attribute as att1, pg_attribute as att2 '
  403. - 'WHERE con.conrelid = cl1.oid '
  404. - 'AND cl1.relname = %s '
  405. - 'AND con.confrelid = cl2.oid '
  406. - 'AND cl2.relname = %s '
  407. - 'AND array_lower(con.conkey, 1) = 1 '
  408. - 'AND con.conkey[1] = att1.attnum '
  409. - 'AND att1.attrelid = cl1.oid '
  410. - 'AND att1.attname = %s '
  411. - 'AND array_lower(con.confkey, 1) = 1 '
  412. - 'AND con.confkey[1] = att2.attnum '
  413. - 'AND att2.attrelid = cl2.oid '
  414. - 'AND att2.attname = %s '
  415. - "AND con.contype = 'f'", (self._table, ref, k, 'id'))
  416. - res2 = cr.dictfetchall()
  417. - if res2:
  418. - if res2[0]['confdeltype'] != POSTGRES_CONFDELTYPES.get(f.ondelete.upper(), 'a'):
  419. - cr.execute('ALTER TABLE "' + self._table + '" DROP CONSTRAINT "' + res2[0]['conname'] + '"')
  420. - self._foreign_keys.append((self._table, k, ref, f.ondelete))
  421. - cr.commit()
  422. - self.__schema.debug("Table '%s': column '%s': XXX",
  423. - self._table, k)
  424. -
  425. - # The field doesn't exist in database. Create it if necessary.
  426. - else:
  427. - if not isinstance(f, fields.function) or f.store:
  428. - # add the missing field
  429. - cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
  430. - cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'", "''")))
  431. - self.__schema.debug("Table '%s': added column '%s' with definition=%s",
  432. - self._table, k, get_pg_type(f)[1])
  433. -
  434. - # initialize it
  435. - if not create and k in self._defaults:
  436. - if callable(self._defaults[k]):
  437. - default = self._defaults[k](self, cr, ROOT_USER_ID, context)
  438. - else:
  439. - default = self._defaults[k]
  440. -
  441. - ss = self._columns[k]._symbol_set
  442. - query = 'UPDATE "%s" SET "%s"=%s' % (self._table, k, ss[0])
  443. - cr.execute(query, (ss[1](default),))
  444. - cr.commit()
  445. - netsvc.Logger().notifyChannel('data', netsvc.LOG_DEBUG, "Table '%s': setting default value of new column %s" % (self._table, k))
  446. -
  447. - # remember the functions to call for the stored fields
  448. - if isinstance(f, fields.function):
  449. - order = 10
  450. - if f.store is not True: # i.e. if f.store is a dict
  451. - order = f.store[f.store.keys()[0]][2]
  452. - todo_end.append((order, self._update_store, (f, k)))
  453. -
  454. - # and add constraints if needed
  455. - if isinstance(f, fields.many2one):
  456. - if not self.pool.get(f._obj):
  457. - raise except_orm('Programming Error', ('There is no reference available for %s') % (f._obj,))
  458. - ref = self.pool.get(f._obj)._table
  459. - # ir_actions is inherited so foreign key doesn't work on it
  460. - if ref != 'ir_actions':
  461. - self._foreign_keys.append((self._table, k, ref, f.ondelete))
  462. - self.__schema.debug("Table '%s': added foreign key '%s' with definition=REFERENCES \"%s\" ON DELETE %s",
  463. - self._table, k, ref, f.ondelete)
  464. - if f.select:
  465. - cr.execute('CREATE INDEX "%s_%s_index" ON "%s" ("%s")' % (self._table, k, self._table, k))
  466. - if f.required:
  467. - try:
  468. - cr.commit()
  469. - cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % (self._table, k), log_exceptions=False)
  470. - self.__schema.debug("Table '%s': column '%s': added a NOT NULL constraint",
  471. - self._table, k)
  472. - except Exception:
  473. - msg = "WARNING: unable to set column %s of table %s not null !\n"\
  474. - "Try to re-run: openerp-server --update=module\n"\
  475. - "If it doesn't work, update records and execute manually:\n"\
  476. - "ALTER TABLE %s ALTER COLUMN %s SET NOT NULL"
  477. - self.__logger.warn(msg, k, self._table, self._table, k)
  478. - cr.commit()
  479. -
  480. + todo = self.update_field(cr, create, column_data, k, f, context=context)
  481. + if todo:
  482. + todo_end.append(todo)
  483. +
  484. else:
  485. cr.execute("SELECT relname FROM pg_class WHERE relkind IN ('r','v') AND relname=%s", (self._table,))
  486. create = not bool(cr.fetchone())
Add Comment
Please, Sign In to add comment